简体   繁体   中英

How can I remove the warning “Cannot match several associated values at once”

I have a helper method in my unit tests:

  func expect(_ sut: CompanyStore, toRetrieve expectedResult: RetrieveCacheResult, when action: @escaping (() -> Void), file: StaticString = #file, line: UInt = #line) {
    let exp = expectation(description: "await completion")

    sut.retrieve { retrievedResult in
      switch (expectedResult, retrievedResult) {
      case (.empty, .empty), (.failure, .failure):
        break
      case let (.found(retrieved), .found(expected)):
        XCTAssertEqual(retrieved.item, expected.item, file: file, line: line)
        XCTAssertEqual(retrieved.timestamp, expected.timestamp, file: file, line: line)

      default:
        XCTFail("Expected to retrieve \(expectedResult), got \(retrievedResult) instead", file: file, line: line)
      }

      exp.fulfill()
    }
    action()
    wait(for: [exp], timeout: 1.0)
  }

It allows me to create tests such as:

  func test_retrieve_delivers_empty_on_empty_cache() {
    let sut = makeSUT()
    expect(sut, toRetrieve: .empty, when: {
      // some action to perform
    })
  }

Since upgrading to Swift 5.1 I am getting the following warning:

Cannot match several associated values at once, implicitly tupling the associated values and trying to match that instead

On the following line

 case let (.found(retrieved), .found(expected)):

These values are a tuple (item: LocalCompany, timestamp: Date)

I haven't been able to work out how to clear this warning.

Edit:

.found is an enum:

public enum RetrieveCacheResult {
  case empty
  case found(item: LocalCompany, timestamp: Date)
  case failure(Error)
}

You have two options:

  1. Redefine the associated value to be a tuple.
case found( (item: Int, timestamp: Bool) )
  1. Extract all the members individually.
case let (
  .found(retrievedItem, retrievedTimestamp),
  .found(expectedItem, expectedTimestamp)
):
  1. Example you have this: case todo(shoppingCount: Int, eating: Bool)
  2. In usage:

           case .todo(let shoppingCount, _):
               print("Shopping count = ", shoppingCount)

           case .todo(_, let eating):
               print("Eating = ", eating)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM