Skip to content

Instantly share code, notes, and snippets.

@erica

erica/attempts.swift

Last active Jul 7, 2020
Embed
What would you like to do?
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"
}
@erica

This comment has been minimized.

Copy link
Owner Author

@erica erica commented Jul 7, 2020

@greg’s solution has the advantage of the greatest readability and elegance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.