What does an exclamation mark mean in the Swift language?

If john were an optional var (declared thusly)

var john: Person?

then it would be possible for john to have no value (in ObjC parlance, nil value)

The exclamation point basically tells the compiler "I know this has a value, you don't need to test for it". If you didn't want to use it, you could conditionally test for it:

if let otherPerson = john {
    otherPerson.apartment = number73
}

The interior of this will only evaluate if john has a value.


TL;DR

What does an exclamation mark mean in the Swift language?

The exclamation mark effectively says, “I know that this optional definitely has a value; please use it.” This is known as forced unwrapping of the optional’s value:

Example

let possibleString: String? = "An optional string."
print(possibleString!) // requires an exclamation mark to access its value
// prints "An optional string."

let assumedString: String! = "An implicitly unwrapped optional string."
print(assumedString)  // no exclamation mark is needed to access its value
// prints "An implicitly unwrapped optional string."

Source: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_399


What does it mean to "unwrap the instance"? Why is it necessary?

As far as I can work out (this is very new to me, too)...

The term "wrapped" implies we should think of an Optional variable as a present, wrapped in shiny paper, which might (sadly!) be empty.

When "wrapped", the value of an Optional variable is an enum with two possible values (a little like a Boolean). This enum describes whether the variable holds a value (Some(T)), or not (None).

If there is a value, this can be obtained by "unwrapping" the variable (obtaining the T from Some(T)).

How is john!.apartment = number73 different from john.apartment = number73? (Paraphrased)

If you write the name of an Optional variable (eg text john, without the !), this refers to the "wrapped" enum (Some/None), not the value itself (T). So john isn't an instance of Person, and it doesn't have an apartment member:

john.apartment
// 'Person?' does not have a member named 'apartment'

The actual Person value can be unwrapped in various ways:

  • "forced unwrapping": john! (gives the Person value if it exists, runtime error if it is nil)
  • "optional binding": if let p = john { println(p) } (executes the println if the value exists)
  • "optional chaining": john?.learnAboutSwift() (executes this made-up method if the value exists)

I guess you choose one of these ways to unwrap, depending upon what should happen in the nil case, and how likely that is. This language design forces the nil case to be handled explicitly, which I suppose improves safety over Obj-C (where it is easy to forget to handle the nil case).

Update:

The exclamation mark is also used in the syntax for declaring "Implicitly Unwrapped Optionals".

In the examples so far, the john variable has been declared as var john:Person?, and it is an Optional. If you want the actual value of that variable, you must unwrap it, using one of the three methods above.

If it were declared as var john:Person! instead, the variable would be an Implicitly Unwrapped Optional (see the section with this heading in Apple's book). There is no need to unwrap this kind of variable when accessing the value, and john can be used without additional syntax. But Apple's book says:

Implicitly unwrapped optionals should not be used when there is a possibility of a variable becoming nil at a later point. Always use a normal optional type if you need to check for a nil value during the lifetime of a variable.

Update 2:

The article "Interesting Swift Features" by Mike Ash gives some motivation for optional types. I think it is great, clear writing.

Update 3:

Another useful article about the implicitly unwrapped optional use for the exclamation mark: "Swift and the Last Mile" by Chris Adamson. The article explains that this is a pragmatic measure by Apple used to declare the types used by their Objective-C frameworks which might contain nil. Declaring a type as optional (using ?) or implicitly unwrapped (using !) is "a tradeoff between safety and convenience". In the examples given in the article, Apple have chosen to declare the types as implicitly unwrapped, making the calling code more convenient, but less safe.

Perhaps Apple might comb through their frameworks in the future, removing the uncertainty of implicitly unwrapped ("probably never nil") parameters and replacing them with optional ("certainly could be nil in particular [hopefully, documented!] circumstances") or standard non-optional ("is never nil") declarations, based on the exact behaviour of their Objective-C code.


Here is what I think is the difference:

var john: Person?

Means john can be nil

john?.apartment = number73

The compiler will interpret this line as:

if john != nil {
    john.apartment = number73
}

While

john!.apartment = number73

The compiler will interpret this line as simply:

john.apartment = number73

Hence, using ! will unwrap the if statement, and make it run faster, but if john is nil, then a runtime error will happen.

So wrap here doesn't mean it is memory wrapped, but it means it is code wrapped, in this case it is wrapped with an if statement, and because Apple pay close attention to performance in runtime, they want to give you a way to make your app run with the best possible performance.

Update:

Getting back to this answer after 4 years, as I got the highest reputations from it in Stackoverflow :) I misunderstood a little the meaning of unwrapping at that time. Now after 4 years I believe the meaning of unwrapping here is to expand the code from its original compact form. Also it means removing the vagueness around that object, as we are not sure by definition if it is nil or not. Just like the answer of Ashley above, think about it as a present which could contain nothing in it. But I still think that the unwrapping is code unwrapping and not memory based unwrapping as using enum.