Swift: if-let with parallel assignment

I am trying to make a simple if-let statement with more than one value. The if block should be executed only if all the optional vars are not equal to zero, plus they should be assigned to new let-vars (constants?), Which live only inside the if block, as well as the usual single-task if so.

 var a: String? = "A" var b: String? // nil if let (m, n) = (a, b) { println("m: \(m), n: \(n)") } else { println("too bad") } // error: Bound value in a conditional binding must be of Optional type // this of course is because the tuple itself is not an Optional // let try that to be sure that the problem... let mysteryTuple: (String?, String?)? = (a, b) if let (m, n) = mysteryTuple { println("m: \(m), n: \(n)") } else { println("too bad") } // yeah, no errors, but not the behavior I want (printed "m: A, n: nil") // and in a different way: if let m = a, n = b { println("m: \(m), n: \(n)") } else { println("too bad") } // a couple syntax errors (even though 'let m = a, n = b' // works on its own, outside the if statement) 

Is it possible? If not (which I guess), do you think that Apple will (or should) implement this in the future?

+6
source share
2 answers

Before deciding whether this is possible or not, consider why the if - let ... conditions work with one optional value: the reason this code compiles

 if let constVar = testVar { ... } 

lies in the fact that all optional types comply with the LogicalValue protocol, which handles a null check on an optional value.

This explains why your trick with the extra tuple didn't work either: the LogicalValue implementation LogicalValue checked if the tuple itself is not null, ignoring its components. The logic of Apple's solution is obvious: instead of making an exception for tuples, when all their element types are optional, they used a single approach and treated the tuple in the same way as other optional types.

Of course, implementing the logic you are trying to implement is easy with an extra line of code:

 if a != nil && b != nil { let (m, n) = (a!, b!) println("m: \(m), n: \(n)") } else { println("too bad") } 
+7
source

This is probably obvious now, but your search for this expected functionality may end with the release of Swift 1.2.

From a quick blog: https://developer.apple.com/swift/blog/?id=22

A more powerful deployment option with if let - The if let construct now you can deploy several options at once, as well as enable intermediate Boolean conditions. This allows you to express a conditional control flow without unnecessary investment.

However, it is now that you can do what you ask, in addition to limiting values ​​with where clauses.

 if let a = foo(), b = bar() { } 
+9
source

Source: https://habr.com/ru/post/972465/


All Articles