什么是“!"和 '?'在 Swift 中使用的标记 [英] What are '!' and '?' marks used for in Swift

查看:563
本文介绍了什么是“!"和 '?'在 Swift 中使用的标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从 Objective-C 改为 Swift 编程时,我遇到了 '!'(感叹号)和 '>?'(问号),通常必须放在 propertymethod 调用等之后.这些标记的用途是什么?如果我们不使用它们会发生什么?

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.

推荐答案

用于这些标记的术语是 Optional Chaining.它们一般用于区分情况,例如,一个property是否是,一个方法调用返回nil.

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.

Apple 的语言指南中解释的示例 Optional Chaining 很好地展示了它们的用途:

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

首先定义了两个名为PersonResidence的类:

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

有一个可选的 residence 属性,类型为 Residence?.

have an optional residence property of type Residence?.

如果你创建一个新的 Person 实例,它的 residence 属性是由于是可选的,默认初始化为 nil.在代码中下面,johnresidence 属性值为 nil:

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

如果您尝试访问此人的 numberOfRooms 属性residence,通过在 residence 后面放置一个感叹号强制展开其值,您会触发运行时错误,因为没有要解包的 residence 值:

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

john.residence 有一个 non-nil 值时,上面的代码成功并将 roomCount 设置为包含适当的 Int 值房间的数量.但是,此代码始终触发 运行时错误,当residencenil 时,如上图所示.

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

这告诉 Swift 在可选的 residence 属性上chain"并在 residence 存在时检索 numberOfRooms 的值.

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

因为尝试访问 numberOfRooms 有可能失败,可选链接尝试返回 Int? 类型的值,或可选 Int".当 residencenil 时,如示例所示上面这个可选的Int也将是nil,以反映事实无法访问 numberOfRooms.可选的 Int通过可选绑定访问以解开整数并分配roomCount 变量的非可选值.

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.

请注意,即使 numberOfRooms 是一个 非可选Int.通过可选链查询的事实意味着对 numberOfRooms 的调用将始终返回 Int? 而不是Int.

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.

您可以将 Residence 实例分配给 john.residence,以便它不再有 nil 值:

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

john.residence = Residence()

除了上面对可选链的一般概述之外,您还可以查看 StackOverflow 中的这个答案.

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.

这篇关于什么是“!"和 '?'在 Swift 中使用的标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆