Swift Variable Decorations With "" (Question Mark) and "!" (Exclamation Mark)

Swift variable decorations with ? (question mark) and ! (exclamation mark)

In a type declaration the ! is similar to the ?. Both are an optional, but the ! is an "implicitly unwrapped" optional, meaning that you do not have to unwrap it to access the value (but it can still be nil).

This is basically the behavior we already had in objective-c. A value can be nil, and you have to check for it, but you can also just access the value directly as if it wasn't an optional (with the important difference that if you don't check for nil you'll get a runtime error)

// Cannot be nil
var x: Int = 1

// The type here is not "Int", it's "Optional Int"
var y: Int? = 2

// The type here is "Implicitly Unwrapped Optional Int"
var z: Int! = 3

Usage:

// you can add x and z
x + z == 4

// ...but not x and y, because y needs to be unwrapped
x + y // error

// to add x and y you need to do:
x + y!

// but you *should* do this:
if let y_val = y {
x + y_val
}

What does an exclamation mark mean in the Swift language?

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.

Swift Type Inference requires question mark or exclamation point

That's not type inference. If you declare a variable's type, inference doesn't happen. Inference is all about figuring (inferring) out what a type is if you don't say explicitly.

You're having a problem with Swift initializer rules. If you declare that a class has this property:

var sut: ItemManager

Then that's non-optional, which means it must have a value by the time initialization is complete. You're not doing that, so Swift is complaining about your initializers. You can either add an init method that assigns a value or you could declare it and assign a value at the same time-- which might look like this:

var sut: ItemManager = ItemManager()

If you declare it like this:

var sut: ItemManager?

Then it's optional, which means if you don't assign a value then it gets a value of nil. You don't have to assign a value during initialization because it already has one.

Exclamation mark prefix on variables during if statements and other as well?

the exclamation mark ! is used for two purposes. When you see it appear at the beginning of an object, such as in !contains(items, values), it means "NOT". For example...

let x = 10
let y = 5

if x == y {
print("x is equal to y")
} else if x != y {
print("x is NOT equal to y")
}

The above code will print => "x is NOT equal to y" .

The logical NOT (!) operator can be used to reverse boolean values. For example...

    var falseBoolValue = false

falseBoolValue = !falseBoolValue
print(falseBoolValue)

The above code will print => "true"

In addition to the usage as the logical NOT operator, the exclamation mark is also used to implicitly unwrap optional values. Whenever you see the exclamation mark appear at the end of an object name, such as in someVariable!, it is being used to implicitly unwrap an optional value. Read about optionals to gain a better understanding of how ! is used with optional values.

Swift optional variable assignment with default value (double question marks)

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.)

Swift : Difference in '!' and '?' in swift

There are two types of variables in Swift.

  1. Optional Variables
  2. Normal(Non-Optional) Variables

Optional Variables:
The shortest description is Optional variables/objects contains the the property "object-returns-nil-when-non-exist". In objC almost all the object we create is optional variable only. That is the objects has the property "object-returns-nil-when-non-exist" behavior. However, this particular behavior is not needed all the time. So, to identify the optionals the symbols '?' and '!' has been used. Again there are two type of optionals...

  • Normal Optionals(?)
  • Implicitly unwrapped optionals(!)

Normal optionals:

var normalOptional : String?

Implicitly unwrapped optionals:

var specialOptional : String!

Both are having the "optional" behaviour, but the difference is the 'Implicitly unwrapped optional' can also be used as a normal(non-optional) value.

For instance, the indexPath variable is declared in the function(cellForRowAtIndex) parameter list by default tableview delegate methods. The row value exists when the cellForRowAtIndex is get called. There, the indexPath variable is declared in the function(cellForRowAtIndex) parameter list.
So, the unwrapping of 'row' value from 'indexPath' is as follows.

       var rowValue = indexPath?.row // variable rowValue inferred as optional Int value
or
var rowValue = indexPath!.row// variable rowValue inferred as normal Int value

Note: When using the '!' unwrapping, have to be very sure that the particular class exists(contains value).

Hope this link will gives you more idea. What is the intended use of optional variable/constant in swift



Related Topics



Leave a reply



Submit