Last active
July 16, 2021 01:50
-
-
Save apua/34a8420620b467bec541c9bbec83d464 to your computer and use it in GitHub Desktop.
pattern matching in Swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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