Last active
July 7, 2020 17:07
-
-
Save erica/c8e540ea2f4987d00799fde9fa0f3f96 to your computer and use it in GitHub Desktop.
This file contains 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
Olivier: I think that's one of the rare cases where fallthough is acceptable | |
import XCTest | |
class Tester: XCTestCase { | |
func testit() { | |
XCTAssertEqual("a", switchTheFallthroughOrder(foo: .a)) | |
XCTAssertEqual("b", switchTheFallthroughOrder(foo: .b("x"))) | |
XCTAssertEqual("c", switchTheFallthroughOrder(foo: .b("cx"))) | |
XCTAssertEqual("c", switchTheFallthroughOrder(foo: .c)) | |
} | |
} | |
Tester.defaultTestSuite.run() | |
// Goal | |
func Goal() -> String { | |
switch foo { | |
case .a: return "a" | |
// Error: str must be bound in every pattern | |
case .b(let str) where str.hasPrefix("c"), .c: return "c" | |
case .b: return "b" | |
} | |
} | |
// Fallthrough doesn't work | |
func test1() -> String { | |
switch foo { | |
case .a: return "a" | |
// Error: fallthrough from a case which doesn't bind variable 'str' | |
case .c: fallthrough | |
case .b(let str) where str.hasPrefix("c"): return "c" | |
case .b: return "b" | |
} | |
} | |
func obviousWayButNotDesired() -> String { | |
switch foo { | |
case .a: return "a" | |
case .c: return "c" | |
case .b(let str) where str.hasPrefix("c"): return "c" | |
case .b: return "b" | |
} | |
} | |
// By default, the ~= operator compares two values of the same type using the == operator. | |
func test2() -> String { | |
switch foo { | |
case .a: return "a" | |
// Error: Operator function ~= requires that Foo conform to Equatable | |
case _ where foo ~= .c : return "c" | |
case .b(let str) where str.hasPrefix("c"): return "c" | |
case .b: return "b" | |
} | |
} | |
/* | |
error: macOS.playground:23:26: error: expected expression for 'where' guard of 'case' | |
case .c(let _) where let str = "c": fallthrough | |
^ | |
error: macOS.playground:23:26: error: expected ':' after 'case' | |
case .c(let _) where let str = "c": fallthrough | |
^ | |
error: macOS.playground:23:39: error: consecutive statements on a line must be separated by ';' | |
case .c(let _) where let str = "c": fallthrough | |
^ | |
; | |
error: macOS.playground:23:39: error: expected expression | |
case .c(let _) where let str = "c": fallthrough | |
^ | |
*/ | |
func test3() -> String { | |
switch foo { | |
case .a: return "a" | |
case .c(let _) where let str = "c": fallthrough | |
case.b(let str) where str.hasPrefix("c"): return "c" | |
case .b: return "b" | |
} | |
} | |
// Also a non-winner although it works: | |
func alsoNotDesired() -> String { | |
switch foo { | |
case .a: return "a" | |
case .b(let str) where !str.hasPrefix("c"): return "b" | |
default: return "c" | |
} | |
} | |
// Greg Titus: You can fallthrough into scopes with FEWER variables defined, so this order works: | |
case .b(let str) where str.hasPrefix("c"): | |
fallthrough | |
case .c: return "c" | |
// Suyash Srijan 10:52 AM | |
// I think the best you can do is something like this: | |
switch foo { | |
case .a: return "a" | |
case .b: | |
guard case let .b(str) = foo, str.hasPrefix("c") else { | |
return "b" | |
} | |
fallthrough | |
case .c: return "c" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@greg’s solution has the advantage of the greatest readability and elegance