I think this form is the best, and it's the most informative for programmers, because it explicitly shows that bar assignment is done only through a certain code path, so if bar wasn't already initialized before the if block, it cannot actually be considered initialized after it, and cannot be used.
That is, this code would not (and should not) compile:
let bar: Bar
if let foo {
bar = foo
}
_ = bar // error: used before initialization
So, a specific operator is impossible to use without adding extra functionality related to code path analysis to operators.
The compiler could understand that something like
let bar: Bar
bar = foo?
doesn't guarantee initialization, but this doesn't read right to me: it looks like bar is initialized with nil if foo is nil.
I think the symmetry between bar? = foo and bar = foo? is misleading, because bar? = foo implies that bar has been already initialized, either to some value or to nil, explicitly or implicitly (in fact, writing var bar: Bar? will implicitly initialize bar to nil). To see better the trick, we can see that this code doesn't compile, but not for the reason one might think:
let foo: Bar?
let baz = Bar()
foo? = baz
the error is not that foo is let and cannot be assigned: the error is Constant 'foo' used before being initialized because let foo: Bar? doesn't implicitly initialize foo to nil.
Thus, bar = foo? should only work if bar has been already initialized, but using the regular assignment operator makes it, to me, misleading.
In some cases, code that
- uses syntactic sugar built on top optionals, and
- produces side effects (like assignment)
can become unnecessarily harder to understand, because makes the branching paths unclear.
For example, something like
foo?.bar.forEach { ... } // I'd prefer a regular for-in here, but this can be useful for other reasons
while clean and concise, appears to me less clear than
if let foo {
foo.bar.forEach { ... }
}
The situation is similar for assignment, with the added bonus that delayed assignment uses code path analysis to make sure that a variable or constant has been assigned when used.