In The Swift Programming Language (book of Apple) I've read that you can create optional variables in 2 ways: using a question mark (?) or by using an exclamation mark (!).
The difference is that when you get the value of an optional with (?) you have to use an exclamation mark every time you want the value:
var str: String? = "Question mark?"
println(str!) // Exclamation mark needed
str = nil
While with an (!) you can get it without a suffix:
var str: String! = "Exclamation mark!"
println(str) // No suffix needed
str = nil
What is the difference and why are there 2 ways if there is no difference at all?
The real benefit to using implicitly unwrapped optionals (declared with the !) is related to class initialisation when two classes point to each other and you need to avoid a strong-reference cycle. For example:
Class A <-> Class B
Class A's init routine needs to create (and own) class B, and B needs a weak reference back to A:
Now,
self
to class B's initialiser once it's fully initialised.instanceOfB
must therefore be optional.However, once A's been created it would be annoying to have to access instanceOfB using instanceOfB! since we know that there has to be a B
To avoid this, instanceOfB is declared as an implicity unwrapped optional (instanceOfB!), and we can access it using just instanceOfB. (Furthermore, I suspect that the compiler can optimise the access differently too).
An example of this is given on pages 464 to 466 of the book.
Summary:
Well mentioned by @tarmes above. Noticed another usage of implicit optional:
Lets say I have an optional
Int
:And I'm trying to use optional pattern matching and use this optional
Int
like this:Notice that I'm using implicit optional with local parameter
myFirstInt
making it safe fornil
condition linked with optionalfirstInt
. If now, I makefirstInt
asnil
, it will execute else condition. If, instead, I use force-unwrap withfirstInt
that would lead to crash, something like this:The
String!
kind is called an implicitly unwrapped optional:The values you create with
?
are plain optional values as you mentioned, you should access it via optional binding (if let unwrappedValue = myOptionalValue
) or by using the exclamation point syntaxmyOptionalValue!.doSomething()
.The values you create with
!
are called implicitly unwrapped optionals. With them, you don't need to manually unwrap before using them. When you doval myOptionalValue!.doSomething()
.The value will be automatically unwrapped for you when you use
myOptionalValue
directly, be careful with this though, because accessing an implicitly unwrapped value when there is actually no value in it (when it isnil
) will result in a runtime error.The main difference is that optional chaining fails gracefully when the optional is nil, whereas forced unwrapping triggers a runtime error when the optional is nil.
To reflect the fact that optional chaining can be called on a nil value, the result of an optional chaining call is always an optional value, even if the property, method, or subscript you are querying returns a nonoptional value. You can use this optional return value to check whether the optional chaining call was successful (the returned optional contains a value), or did not succeed due to a nil value in the chain (the returned optional value is nil).
Specifically, the result of an optional chaining call is of the same type as the expected return value, but wrapped in an optional. A property that normally returns an Int will return an Int? when accessed through optional chaining.
For more detail, refer a document by Apple Developer Commitee, in detail
You should go beyond the syntactic sugar.
There are two completely different polymorphic types. The syntactic sugar just uses either one or the other of these types.
When you write
Foo?
as a type you really haveOptional<Foo>
, while when you writeFoo!
you really haveImplicitlyUnwrappedOptional<Foo>
.These are two different types, and they are different from
Foo
as well.