Purely motivated by academic reasons, is there a way I can avoid the if let binding and do something like the second (invalid) snippet?
This does what I want
enum SomeEnum: String { case a, b, c }
for i in ["a", "bb", "b", "c", "cc"] {
if let x = SomeEnum(rawValue: i) {
switch x {
case .a: print(x)
case .b: print(x)
case .c: print(x)
}
}
}
This is invalid syntax, but I want to do something similar to this.
enum SomeEnum: String {case a, b, c}
for i in ["a", "bb", "b", "c", "cc"] {
switch SomeEnum(rawValue: i) {
case let x as .a?:
print(x)
case let x as .b?:
print(x)
case let x as .c?:
print(x)
case nil: print("no match")
}
}
PS: For the sake of this discussion, disregard what the cases do with the enum instance, I am interested in being able to refer the enum instance inside the case statements.
Thanks for responding, not sure I understand, but I want to bind them not just match, my second snippet is basically a variant of what you linked, I did go through that link.
for i in ["a", "bb", "b", "c", "cc"] {
switch SomeEnum(rawValue: i) {
case let x? where x == .a:
print(x)
case let x? where x == .b:
print(x)
case let x? where x == .c:
print(x)
default: print("no match")
}
}
I would still prefer the one involving if let though.
Usually binding is used to extract associated values (the following paragraph in the link). You don't really need bindings to match the entire value - you can just store it before the matching:
enum SomeEnum: String {case a, b, c}
for i in ["a", "bb", "b", "c", "cc"] {
if let x = SomeEnum(rawValue: i)
switch x {
case .a:
print(x)
case .b:
print(x)
case .c:
print(x)
}
} else {
print("no match")
}
}
You could make the conversion and Optional case match on the first line, then you'd be left with just a SomeEnum value inside the loop:
enum SomeEnum: String { case a, b, c }
for case let x? in ["a", "bb", "b", "c", "cc"].map(SomeEnum.init(rawValue:)) {
switch x {
case .a: print(x)
case .b: print(x)
case .c: print(x)
}
}
The other answers here are good, but there is no way to replicate what these two lines are doing, without if, guard, or another switch. Swift has no mechanism to bind a variable for further usage without them.
guard was created explicitly for this.
for i in ["a", "bb", "b", "c", "cc"] {
guard let x = SomeEnum(rawValue: i) else {
print("no match")
continue
}
switch x {
case .a:
print(x)
case .b:
print(x)
case .c:
print(x)
}
}
["a", "bb", "b", "c", "cc"].forEach { i in
guard let x = SomeEnum(rawValue: i) else {
print("no match")
return
}
switch x {
case .a:
print(x)
case .b:
print(x)
case .c:
print(x)
}
}
for i in ["a", "bb", "b", "c", "cc"] {
switch SomeEnum(rawValue: i) {
case let x?:
switch x {
case .a:
print(x)
case .b:
print(x)
case .c:
print(x)
}
case nil: print("no match")
}
}