So I was trying to do
let foo = dict["key"] as? String ?? "empty"
var bar = some_func(string: foo!)
and XCode 6 complains thatOperand of postfix '!' should have optional type; type is 'String'
on the second line.
If I change the first line to
let foo: String? = dict["key"] as? String ?? "empty"
the error goes away.
Is this some kind of flaw or am I just doing something wrong?
Double question mark is a nil-coalescing operator. In plain terms, it is just a shorthand for saying != nil . First it checks if the the return value is nil, if it is indeed nil, then the left value is presented, and if it is nil then the right value is presented.
To use an optional, you "unwrap" it An optional String cannot be used in place of an actual String . To use the wrapped value inside an optional, you have to unwrap it. The simplest way to unwrap an optional is to add a ! after the optional name. This is called "force unwrapping".
However there is another data type in Swift called Optional, whose default value is a null value ( nil ). You can use optional when you want a variable or constant contain no value in it. An optional type may contain a value or absent a value (a null value).
Question marks after a type refer to Optionals , a way in Swift which lets you indicate the possibility that a value might be absent for any type at all, without the need for special constants.
The nil-coalescing operator a ?? b
is a shortcut for
a != nil ? a! : b
it returns either the left operand unwrapped or the right operand. So the type of foo
is String
and the second line should be
var bar = some_func(string: foo)
without the exclamation mark because foo
is not an optional and can't be unwrapped.
(If you change the first line to
let foo: String? = dict["key"] as? String ?? "empty"
then the result of the right hand side is wrapped into an optional string again, and needs to be unwrapped in the second line. It makes the error go away, but this is probably not what you want.)
Your foo
will be a String
not a String?
because the nil coalescing operator ??
will either unwrap your conditional cast if it is .some
(resulting in a String
) or it will use "empty"
, which is also a String
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With