参见英文答案 >
What does an exclamation mark mean in the Swift language?21个答案>
Swift variable decorations with “?” (question mark) and “!” (exclamation mark)
在Swift中有三种方式声明一个属性:
在Swift中有三种方式声明一个属性:
var optStr: String? var normStr: String = "normStr" var exactStr: String!
第一个是具有可选类型的属性,在我们的例子中可以包含nil或String。第二个是一个总是包含String的属性。它应该在初始化或声明中初始化。
但第三种方式呢?
var exactStr: String!
我在操场上做了一些实验,结果发现一个需要类型的功能?可以采取两种类型,类型?并输入!变量作为参数:
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"
那么为什么和何时应该使用类型!
更新:这不是What does an exclamation mark mean in the Swift language?的重复。我不是要求解开一个变量:我问的是声明一个感叹号的属性(Type!)。
它是“implicitly-unwrapped optional String”类型的变量。从本质上讲,implicitStr的每一次访问都被看作是隐含的语句! (从而展开该值)。
这当然会导致崩溃,如果值为零。你仍然可以通过implicitStr!= nil来测试隐含的可选项,或者在可选链接中使用它作为var foo = implicitStr?.uppercaseString。所以你仍然可以像正常的可选项一样安全地使用它;它只是偏向于价值不为零的情况。
在初始化时可能不存在该值的情况下,隐式展开的可选项非常有用,但是设置得很早,不太可能再次变为零。 (例如,在-awakeFromNib中设置的变量可能合理地是一个隐式解包的可选项。)
此外,由于Objective-C方法可以返回nil和对象类型,所以它们的返回值不能被建模为非可选的。为了避免在处理Cocoa API时自由使用强制解包,Cocoa API的参数和返回类型通常表示为隐式解包选项。