What are '!' and '?' marks used for in Swift

人走茶凉 提交于 2019-12-24 13:35:43

问题


When I changed from Objective-C to Swift programming, I have come across '!' (exclamation mark) and '?' (question mark) that often have to be put right after a property, a method call etc. What are these marks used for, and what happens if we did not use them?

I searched for a thorough answer on the web but could not find any. So I decided to put here my answer in case for anyone is in search of a clear answer for that.

I also included in my answer below a link to a question that is similar to mine, where you can find further explanation on how and where you can use these marks (i.e. '!' and '?'). My question asks and my answer explains at a more basic level than the similar question in the link.


回答1:


The terminology used for these marks is Optional Chaining. They are generally used for distinguishing the cases, for example, whether a property is, a method call returns nil.

An example explained in Apple's language guide for Optional Chaining is a good one to show the purpose of their use:

First, two classes called Person and Residence are defined:

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
} Residence instances have a single `Int` property called `numberOfRooms`, with a default value of **1**. `Person` instances

have an optional residence property of type Residence?.

If you create a new Person instance, its residence property is default initialized to nil, by virtue of being optional. In the code below, john has a residence property value of nil:

let john = Person()

If you try to access the numberOfRooms property of this person’s residence, by placing an exclamation mark after residence to force the unwrapping of its value, you trigger a runtime error, because there is no residence value to unwrap:

let roomCount = john.residence!.numberOfRooms
// this triggers a runtime error

The code above succeeds when john.residence has a non-nil value and will set roomCount to an Int value containing the appropriate number of rooms. However, this code always triggers a runtime error when residence is nil, as illustrated above.

Optional chaining provides an alternative way to access the value of numberOfRooms. To use optional chaining, use a question mark in place of the exclamation mark:

if let roomCount = john.residence?.numberOfRooms {
    print("John's residence has \(roomCount) room(s).")
} else {
    print("Unable to retrieve the number of rooms.")
}
// Prints "Unable to retrieve the number of rooms."

This tells Swift to “chain” on the optional residence property and to retrieve the value of numberOfRooms if residence exists.

Because the attempt to access numberOfRooms has the potential to fail, the optional chaining attempt returns a value of type Int?, or “optional Int”. When residence is nil, as in the example above, this optional Int will also be nil, to reflect the fact that it was not possible to access numberOfRooms. The optional Int is accessed through optional binding to unwrap the integer and assign the nonoptional value to the roomCount variable.

Note that this is true even though numberOfRooms is a nonoptional Int. The fact that it is queried through an optional chain means that the call to numberOfRooms will always return an Int? instead of an Int.

You can assign a Residence instance to john.residence, so that it no longer has a nil value:

john.residence = Residence()

Besides the general overview of Optional Chaining above, you can look at this answer in StackOverflow.

Hope this gives you some perspective on Optional Chaining.




回答2:


In simpler terms adding a

!

means you are 100% guaranteed to give a value....if you add a "!" and don't give a value the app will crash saying returned a value that is nil (or something like that).....

?

means you might return a value...this is the better way of doing things if you can help it...



来源:https://stackoverflow.com/questions/37342844/what-are-and-marks-used-for-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!