Reputation: 878
Implicitly unwrapping optionals can be done this way.
if let foo = foo {
print("foo")
} else {
print("bar")
}
I'm practicing in Playground, and what I don't understand is why I can't do the one above using a ternary operator.
let foo = foo ? print("foo") : print("bar")
// or
var result:String = (let foo = foo ? print("foo") : print("bar"))
I was thinking this is perfectly normal, albeit awkward, syntax for Swift since ternary operations evaluate to expressions. My suspicion is that let foo = foo
is itself an expression that Swift has to deal with, but that's coming from a Swift newbie like me.
Upvotes: 0
Views: 2000
Reputation: 385650
if let
is a special Swift form that allows you to rebind an identifier while unwrapping an Optional
. A let
statement by itself can't rebind an identifier declared in the same scope. Them's the rules.
Furthermore, you cannot use an Optional
as if it were a BooleanType
, which you're trying to do (since the conditional of ?:
has to be a BooleanType
).
Also note that print
returns ()
(the empty tuple, also known as the singleton instance of the Void
type). So there's no reason to rebind foo
to the return value of print
.
This works, though it's not good style:
foo != nil ? print("set") : print("nil")
This is good style:
if foo != nil {
print("set")
} else {
print("nil")
}
Or this:
print(foo != nil ? "set" : "nil")
The following is worse in this case, but is a reasonable pattern when you need to transform the wrapped value if set, and provide a default if nil:
print(foo.map { _ in "set" } ?? "nil" )
If you just want to unwrap foo
for use later in the function, without increasing the brace nesting level, you can use guard
:
guard let foo = foo else {
print("nil")
return // you must return or throw or abort here in a guard statement
}
// Here foo has been rebound and is no longer optional.
print("set to \(foo)")
Upvotes: 4