1

当我从编程转变Objective-CSwift编程时,我遇到了' !'(感叹号)和' ?'(问号),它们通常必须放在 a property、 a methodcall 等之后。这些标记是用来做什么的,如果我们没有使用它们?

我在网上搜索了一个彻底的答案,但找不到任何答案。所以我决定把我的答案放在这里,以防有人正在寻找一个明确的答案。

我还在下面的答案中包含了一个与我的问题类似的问题的链接,您可以在其中找到有关如何以及在何处使用这些标记的进一步说明(即“!”和“?”)。与链接中的类似问题相比,我提出的问题和我的回答在更基本的层面上进行了解释。

4

2 回答 2

1

用于这些标记的术语是Optional Chaining。它们通常用于区分情况,例如 aproperty是否,a是否method call返回nil

Apple 的语言指南中Optional Chaining解释的一个示例很好地说明了它们的使用目的:

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

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

如果您创建一个新Person实例,它的residence属性默认初始化为nil,因为它是可选的。john在下面的代码中,residence属性值为nil

let john = Person()

如果你试图访问numberOfRooms这个人的属性 ,通过在后面residence放置一个感叹号residence来强制解包它的值,你会触发一个运行时错误,因为没有residence值可以解包:

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

上面的代码在john.residence具有非零值时成功,并将设置roomCountInt包含适当房间数量的值。但是,此代码在is时总是会触发运行时错误,如上图所示。residencenil

可选链接提供了另一种访问 的值的方法 numberOfRooms。要使用可选链接,请使用问号代替感叹号:

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 在可选属性上“<strong>chain”residence并检索numberOfRoomsif residenceexists 的值。

因为访问尝试numberOfRooms有可能失败,可选链接尝试返回一个类型的值Int?,或“<strong>optional Int”。什么时候residencenil,就像上面的例子一样,这个可选的Int也将是nil,以反映无法访问的事实numberOfRooms。可选项Int 通过可选项绑定访问以解包整数并将非可选值分配给roomCount变量。

请注意,即使numberOfRooms是非可选的也是 Int如此。通过可选链查询它的事实意味着调用numberOfRooms将始终返回 anInt?而不是Int.

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

john.residence = Residence()

除了上面对可选链接的一般概述之外,您还可以在 StackOverflow中查看此答案。

希望这能让您对可选链接有所了解。

于 2016-05-20T09:21:49.280 回答
1

简单来说,添加一个

!

意味着你 100% 保证给出一个值....如果你添加一个“!” 并且不要给出应用程序将崩溃的值,说返回的值为零(或类似的东西).....

?

意味着您可能会返回一个值...如果您能提供帮助,这是更好的做事方式...

于 2016-05-22T03:57:48.750 回答