带有“?”的快速可变装饰 (问号)和“!” (感叹号)


106

我了解在Swift中所有变量都必须设置一个值,并且通过使用可选参数,我们可以将变量设置为nil初始值。

我不明白的是,用a设置变量的作用!是什么,因为我的印象是这会“取消包装”可选值。我认为通过这样做,您可以保证该变量中有一个要解包的值,这就是为什么在IBActions上使用它的原因。

简而言之,执行以下操作时初始化的变量是什么:

var aShape : CAShapeLayer!

以及为什么/何时会这样做?


检查此事实,您可以执行此操作以告知变量为nt nil 。
Matthias 2014年

我认为不应将此标记为重复。“什么是可选的?” 与“两种类型的可选方案有何区别?”的问题不同 这几乎就是这个问题的原因
Jiaaro

@Jiaaro即使在这种情况下,也已经有大量关于可选项,隐式展开的可选项等的问题。您也可以参考以下内容:stackoverflow.com/questions/24272781/…–
杰克

@JackWu好的,但是我很确定这个问题在被问到时不会重复。(例如,在您的示例之前,它被问了整整一周)
Jiaaro 2014年

@Jiaaro你说的很对,我没有注意到这是older..maybe,其他人都不应代替标记为这一个的副本..
杰克

Answers:


145

在类型声明中,!类似于?。两者都是可选的,但是!是“ 隐式展开的”可选的,这意味着您不必解包即可访问值(但它仍可以为nil)。

这基本上是我们在Objective-C中已经拥有的行为。值可以为nil,您必须检查该值,但是您也可以直接访问该值,就好像它不是可选值一样(重要的区别是,如果不检查nil,您将得到一个运行时错误)

// 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

用法:

// 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
}

7
Swift编程语言的第56页开始的一个恰当命名的部分中,对隐式展开的可选内容进行了描述。
Caleb 2014年

@Caleb我添加了一个链接到在线文档的相关部分,在那里我提到的隐含展开自选:)
Jiaaro

很好的信息,谢谢。到目前为止,一般来说,爱上Swift强制我们执行的安全性,应该会减少很多错误:)。
杰森·雷纳尔多2014年

@Jiaaro:非常感谢您的分享。通过以上示例,使用户能够完全理解!!:)
Esha 2014年

3
我认为“ 这基本上是我们在Objective-C中已经存在的行为句话可能会造成混淆。在Objective-C中,人们可以访问一个nil值并实际“使用”它,而在nil为零时快速访问一个隐式展开的可选内容抛出运行时异常。
Sascha Wolf
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.