Skip to content

Instantly share code, notes, and snippets.

@apua
Last active July 16, 2021 01:50
Show Gist options
  • Save apua/34a8420620b467bec541c9bbec83d464 to your computer and use it in GitHub Desktop.
Save apua/34a8420620b467bec541c9bbec83d464 to your computer and use it in GitHub Desktop.
pattern matching in Swift
// Ref: https://fuckingifcaseletsyntax.com
let ONE = 1
enum E { case A, B(Int), C(Int, String) }
for v in 0...3 {
switch v {
case 0: print("0") // match value
case ONE: print("ONE=\(ONE)") // match identifier
case 1..<3: print("in [1,3)") // v ~= 1..<3
case let x: print("x=\(x)") // bind value to identifier
//case _: break // warning: case is already handled by previous patterns; consider removing it
//default: break // warning: default will never be executed
}}
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
for v in [(0,0), (1,1), (2,2)] {
switch v {
case (0,0): print("0,0")
case (1,ONE): print("1,ONE=\(ONE)")
case let (x,y): print("x=\(x),y=\(y)") // decompose elements of tuple
}}
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
for v in [E.A, E.B(1), E.B(2), E.C(3, "4")] /* [E] */ {
switch v {
case .A /* E.A */: print(".A") // match case
case .B(ONE): print(".B(1)") // match case and associated value
case .B /* .B(_) */: print(".B(_)") // match case and associated value by wildcard
default: print(v)
}}
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
for ov in [0, 1, 2, nil] /* [Int?] */ {
switch ov {
case 0?: print("0?")
case .some(1): print("1?")
case .some(let v): print("v=\(v)") // match case `.some` of Optional
//case .some(_): print("some") // warning: case is already handled by previous patterns; consider removing it
case .none: print("none") // match case `.none` of Optional
//case nil: break // warning: case is already handled by previous patterns; consider removing it
//default: break // warning: default will never be executed
}}
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
for ov in [E.C(3,"4"), nil, E.A] /* [E?] */ {
switch ov {
case let .C(x,y)?: print(x,y)
case nil: print("Nothing")
default: print(ov as Any) // explicitly cast to 'Any' with 'as Any' to silence this warning
}}
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
//let oc34: Optional = E.C(3,"4")
let oc34: E? = .C(3,"4")
let oa: E? = .A
switch oc34 { case .A: print("A"); case let .C(x,y)?: print(x,y); default: break }
switch oc34 { case .A: print("A"); case let .C(x,y)? where x == 3: print(x,y); default: break }
switch oc34 { case .A: print("A"); case .C(let x, let y)?: print(x,y); default: break }
// Same as `switch` but not support `where`
if case .A = oa { print(oa as Any) }
if case let c34? = oc34 { print(c34) }
//x// if case let c34? = oc34 where x == 3 { print(c34) }
if case let .C(x,y)? = oc34 { print(x,y) }
if case .C(let x, let y)? = oc34 { print(x,y) }
if let c34 = oc34, case let .C(x,y) = c34 { print(x,y)}
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
if case let c34? = oc34 { print(c34, "if-case-let") }
if let c34 = oc34 { print(c34, "if-let") }
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
// switch value { case pattern, pattern, ..., pattern where condition: break }
for i in 1...2 {
switch i { case 1,2: print("\(i) matches either 1 or 2"); default: break }
switch i { case let x where x > 1: print("\(i) > 1"); default: break }
}
// if case pattern = value, condition {}
for i in 1...2 {
//x// if case 1,2 { print("\(i) matches 1 or 2") }
//x// if case 1,2 = i { print("\(i) matches 1 or 2") }
if case 1 = i, case 2 = i {} else { print("\(i) not match both 1 and 2") }
if case let x = i, x > 1 { print("\(i) > 1") }
}
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
switch nil as Optional<Int> { case _?: break; case nil: print("Nothing") }
if case _? = nil as Optional<Int> {} else { print("Nothing") }
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
// `~=` is used for "expression pattern", e.g. `1...3`
1...3 ~= 2 // true
if 1...3 ~= 2 { print("2 in 1...3") }
switch 2 { case 1...3: print("2 in 1...3"); default: break }
1 ~= Optional(1)
switch Optional(1) { case 1: print("1 match `1?`"); default: break }
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
for i in [0,1,nil,2].compactMap{$0} { print(i) }
for case let i? in [0,1,nil,2] { print(i) }
for case .some in [0,1,nil,2] { print("count") }
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
for case let .B(i) in [E.A, E.B(1), E.B(2)] { print(i) }
for e in [E.A, E.B(1), E.B(2)] { if case let .B(i) = e { print(i) } }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment