I\'m trying to use a tuple as an optional binding in an IF statement in Swift but it won\'t compile and that error message is less than helpful. Why doesn\'t the following
Let's say we have tuple having two optional Ints. To unwrap it we can optionally cast it to (Int, Int) using as?. If any of them is nil then it won't be able to cast it. If it does we will get unwrapped values from that tuple.
let tuple: (Int?, Int?) = (1, 2)
if let (value1, value2) = tuple as? (Int, Int) {
print("value1: \(value1), value2: \(value2)")
}
//value1: 1, value2: 2
You have to use a switch
as the other answer points out. However, if you're only going to check both values, an if
without Optional Binding is actually shorter and easier-to-read.
if (user != nil && pass != nil) {
print("this works: \(user!), \(pass!)")
}
The switch
is goofy and hard-to-read (taken from other answer), but if you're going to use the other cases (nil-some, some-nil, nil-nil) then it might be worth it.
switch (user, pass) {
case let (.Some(user), .Some(pass)): print("this works: \(user), \(pass)")
default: ()
}
In Swift 2 with optional pattern matching you can write
if case let (user?, pass?) = (user, pass) { }
This is especially useful if, for example, (user, pass) is a tuple stored in a variable.
edit: as of Swift 1.2 in Xcode 6.3, you can now do:
if let user = user, pass = pass { }
to bind multiple unwrapped optional values.
You can't use optional let binding that way. let test = (user,pass)
won't compile since (user,pass)
is not an optional – it's a tuple that contains optionals. That is, it's an (Int?,Int?)
not an (Int,Int)?
.
This should do what you want and allows you to bind two items simultaneously:
switch (user, pass) {
case let (.Some(user), .Some(pass)):
print("this works: \(user), \(pass)")
default: () // must handle all cases
}