在Swift语言中,属性中的惊叹号是什么?(复制)

时间:2022-01-14 22:28:35

This question already has an answer here:

这个问题已经有了答案:

There are three way to declare a property in Swift:

在Swift中申报财产有三种方式:

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

The first one is property with an optional type, a type that can contain either nil or the String in our case. The second one is a property that always contain the String. It should be initialized in init or in the declaration.

第一个是具有可选类型的属性,该类型可以包含nil或字符串。第二个属性总是包含字符串。它应该在init或声明中初始化。

But what about the third way?

但是第三条呢?

var exactStr: String!

I made some experiments in the playground, and it turned out that a function that takes type? can take both type, type? and type! variables as an argument:

我在操场上做了一些实验,结果发现一个需要打字的函数?两种都可以吗?和类型!变量作为参数:

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"

So why and when should I use type!?

那么为什么我应该在什么时候使用type呢?

Update: this is not a duplicate of What does an exclamation mark mean in the Swift language?. I'm not asking about unwrapping a variable: I'm asking about declaring a property with an exclamation point (Type!).

更新:这不是一个重复的什么惊叹号在斯威夫特的语言?我不是在询问如何展开一个变量:我是在询问如何使用感叹号(类型!)声明一个属性。

1 个解决方案

#1


49  

It's a variable of type "implicitly-unwrapped optional String". Essentially, every access of implicitStr is treated as if it were written implicitStr! (thus unwrapping the value).

它是“隐含未包装的可选字符串”类型的变量。本质上,所有对implicitStr的访问都被视为“implicitStr”字。(因此展开的值)。

This, of course, will cause a crash if the value is nil. You can still test the implicit optional via if implicitStr != nil, or use it in optional chaining as var foo = implicitStr?.uppercaseString. So you can still use it just as safely as a normal optional; it's just biased toward the case where the value is not nil.

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

Implicitly-unwrapped optionals are quite useful in cases where the value may not be present at initialization, but are set early and unlikely to become nil again. (For example, a variable you set in -awakeFromNib might reasonably be an implicitly-unwrapped optional.)

当值在初始化时可能不存在,但在早期就被设置,并且不太可能再次变为nil时,隐含的未包装选项是非常有用的。(例如,您在- awfromakenib中设置的变量可能是一个隐含的未包装的可选变量。)

Further, since Objective-C methods can return both nil and object types, their return values cannot be modeled as non-optional. To avoid requiring liberal use of forced unwrapping whenever dealing with Cocoa APIs, though, the parameters and return types of Cocoa APIs are usually represented as implicitly-unwrapped optionals.

此外,由于Objective-C方法可以同时返回nil和对象类型,因此不能将它们的返回值建模为非可选的。但是,为了避免在处理Cocoa api时使用强制展开,Cocoa api的参数和返回类型通常被表示为隐含的未封装的选项。

#1


49  

It's a variable of type "implicitly-unwrapped optional String". Essentially, every access of implicitStr is treated as if it were written implicitStr! (thus unwrapping the value).

它是“隐含未包装的可选字符串”类型的变量。本质上,所有对implicitStr的访问都被视为“implicitStr”字。(因此展开的值)。

This, of course, will cause a crash if the value is nil. You can still test the implicit optional via if implicitStr != nil, or use it in optional chaining as var foo = implicitStr?.uppercaseString. So you can still use it just as safely as a normal optional; it's just biased toward the case where the value is not nil.

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

Implicitly-unwrapped optionals are quite useful in cases where the value may not be present at initialization, but are set early and unlikely to become nil again. (For example, a variable you set in -awakeFromNib might reasonably be an implicitly-unwrapped optional.)

当值在初始化时可能不存在,但在早期就被设置,并且不太可能再次变为nil时,隐含的未包装选项是非常有用的。(例如,您在- awfromakenib中设置的变量可能是一个隐含的未包装的可选变量。)

Further, since Objective-C methods can return both nil and object types, their return values cannot be modeled as non-optional. To avoid requiring liberal use of forced unwrapping whenever dealing with Cocoa APIs, though, the parameters and return types of Cocoa APIs are usually represented as implicitly-unwrapped optionals.

此外,由于Objective-C方法可以同时返回nil和对象类型,因此不能将它们的返回值建模为非可选的。但是,为了避免在处理Cocoa api时使用强制展开,Cocoa api的参数和返回类型通常被表示为隐含的未封装的选项。