Swift Pattern Matching with Enum and Optional Tuple Associated Values

Swift pattern matching with enum and Optional tuple associated values

You can use the .Some(x) pattern (.some(x) in Swift 3):

case .GetStops(let .Some(stopCode)):
return ("GetStops.json", ["stopCode" : stopCode])

As of Swift 2 (Xcode 7), this can be shorter written as x? pattern:

case .GetStops(let stopCode?):
return ("GetStops.json", ["stopCode" : stopCode])

The associated value is tested to be non-nil and unwrapped (similar as in an optional binding).

Swift Compiler Error: The enum case has a single tuple as an associated value, but there are several patterns here

Ok, figured it out. Seems like enum with associated values, where the value type is a tuple, can no longer be matched on a switch statement like that:

// Works on Xcode 11.3.1, yields error on 11.4 (Swift 5.2)
switch result {
case .error(let err):
//
case .value(let staff, let locations):
//
}

Solution

Values from tuple have to be manually extracted in Xcode 11.4 (Swift 5.2):

// Works on Xcode 11.4
switch result {
case .error(let err):
//
case .value(let tuple):
let (staff, locations) = tuple
//
}

Extract associated value of enum case into a tuple

You can use pattern matching with if case let to extract the
associated value of one specific enumeration value:

if case let Barcode.upc(first, second, third, fourth) = productBarcode {
print((first, second, third, fourth)) // (8, 10, 15, 2)
}

or

if case let Barcode.upc(tuple) = productBarcode {
print(tuple) // (8, 10, 15, 2)
}

Swift enum - switch statement matching associated values warning

Spell it like

case .entry0(let x, _):

Or like

case let .entry0(x, _):

which works more generally like:

case let .entry0(x, y):

Swift Enum: Expression pattern matching issue

Pattern matching uses Equatable internally, so you should change your Fruit class:

extension Fruit: Equatable {
static func == (lhs: Fruit, rhs: Fruit) -> Bool {
return lhs.name == rhs.name // or every field if you want
}
}

If you want to use the reference, simply change the == func to return true if both references are equal, but I don't think it's a good idea:

static func == (lhs: Fruit, rhs: Fruit) -> Bool {
return lhs === rhs
}

Unwrap optional properties automatically in enum

Use optional enum's .some binding:

enum StoreAPI {
case newNote(String, Data?)
}

// sample data
let api = StoreAPI.newNote("title", "data".data(using: .utf8))

switch api {

case let .newNote(title, .some(data)):
print("title: \(title), data: \(data)")

default:
break

}

Type annotated tuple pattern in case statement?

The syntax is:

func F<T1, T2>(_ t: (T1, T2)) {
switch t {
case let (x, y) as (Int, String):
// do something
default:
// do something else
}
}


Related Topics



Leave a reply



Submit