Swift语言中属性中的感叹号是什么?

时间:2014-06-18 13:17:55

标签: swift

在Swift中声明属性有三种方法:

var optStr: String?
var normStr: String = "normStr"
var exactStr: String!

第一个是optional类型的属性,在我们的例子中可以包含nil或String的类型。第二个是始终包含String的属性。它应该在init或声明中初始化。

但是第三种方式呢?

var exactStr: String!

我在操场上做了一些实验,结果表明,type?的函数可以将typetype?type!变量作为参数:

var optStr: String?
var normStr: String
var forcedStr: String!

func printStr(str: String?) {
    println("str: \(str)")
}

printStr(optStr) //prints: "str: nil"
//printStr(normStr) //doesn't compile as not initialized
printStr(forcedStr) //prints: "str: nil"

optStr = "optStr"; normStr = "normStr"; forcedStr = "forcedStr"

printStr(optStr) //prints "str: optStr"
printStr(normStr) //prints "str: normStr"
printStr(forcedStr) //prints "str: forcedStr"

那么为什么以及何时应该使用type!

更新:这不是What does an exclamation mark mean in the Swift language?的重复。我没有询问展开变量:我问declaring一个带感叹号的属性(Type!)。

1 个答案:

答案 0 :(得分:65)

它是"隐式解包的可选字符串"类型的变量。从本质上讲,implicitStr的每次访问都被视为写入implicitStr!(因此展开了值)。

当然,如果值为零,这将导致崩溃。您仍然可以通过if implicitStr != nil测试隐式可选项,或者在可选链接中将其用作var foo = implicitStr?.uppercaseString。所以你仍然可以像普通的可选项一样安全地使用它;它只是偏向于价值不是零的情况。

隐式解包的选项在初始化时可能不存在的情况下非常有用,但是提前设置并且不太可能再次变为零。 (例如,您在-awakeFromNib中设置的变量可能合理地是一个隐式解包的可选项。)

此外,由于Objective-C方法可以返回nil和object类型,因此无法将其返回值建模为非可选。但是,为避免在处理Cocoa API时需要自由使用强制解包,Cocoa API的参数和返回类型通常表示为隐式解包的选项。