Swift 可选项,展开
Swift optionals, unwrapping
我正在学习 swift 语法,对可选类型有点困惑。
因此,根据定义,swift 类型不能存储空值,除非它被显式定义为可选。那么,下一行的变量在声明时包含什么。
var a:Int (declaring a variable without intializing it working fine in swift 3)
而且当我们将变量声明为带有“!”的可选变量时,
var optionalSquare: Square! = Square(sideLength: 10, name: "Optional Square")
如果我们想使用 "optionalSquare" 变量,我们不需要打开它因为我们确定(我认为这就是我们使用“!”而不是“?”的原因)它不会包含任何空值。那么我们为什么不将其声明为普通变量呢。
请更正任何不实陈述。谢谢。
what does [var a:Int
] contains when it's declared
没有。它的值是未定义的。 在赋值之前使用它是编译错误。你可以声明它而不初始化它,但是你不能使用它。
这是 Swift 安全哲学的重要组成部分:在 C 中,您同样可以保留一个未初始化的变量,它的值将是未定义的,但编译器不会(默认情况下)报告如果你使用它会出错。
so why don't we declare it as a normal variable.
我没有理由想到使局部变量成为隐式解包的可选变量。该功能适用于结构或 类 上的 properties ("ivars")。您应该在不可能在对象的 init
中设置 属性 的地方使用它们,但可以肯定的是,在使用对象之前该值将存在。
IBOutlet
s 可能是典型的用例。我发现另一个有用的用途是允许通过调用 init
.
中的方法来设置 属性
您可以声明一个非可选变量而不对其进行初始化 - 只要您不使用该变量,编译器就不会报错。所以这段代码
var num: Int
不会产生任何错误。但是,如果您在初始化之前引用该变量,编译将失败
var num: Int
print(num)
在前一种情况下没有错误,因为可以推迟初始化。您可以声明一个变量,然后在 100 行之后进行初始化。只要你在初始化之前不引用它,你就可以。
要回答你的第二个问题,可以这样说,在许多情况下,声明和上下文初始化隐式展开的变量没有多大意义:非可选变量更合适。
So, what does the variable in the following line contains when it's declared.
没关系,因为你无论如何都无法访问它。像这样的声明告诉 Swift 您稍后将决定该值。在分配之前读取变量是编译器将要捕获的错误。
why don't we declare [variables with forced unwrapping] it as a normal variables?
因为您可能想在不应该使用它的时候将 nil
存储在该变量中。
例如,您应该使 IB 分配的 属性 隐式展开,因为它们需要 nil
在 NIB 对象 "inflated" 之前,但在 init
之后方法已完成:
@IBOutlet private weak var myLabel: UILabel!
为了使 myLabel
成为非可选的,您必须删除 weak
。另一方面,您不想在每次访问 myLabel
时都使用感叹号,因为您确定它必须被初始化。
同样的推理适用于您希望设为非可选但不能在初始值设定项中赋值的其他变量。
我正在学习 swift 语法,对可选类型有点困惑。 因此,根据定义,swift 类型不能存储空值,除非它被显式定义为可选。那么,下一行的变量在声明时包含什么。
var a:Int (declaring a variable without intializing it working fine in swift 3)
而且当我们将变量声明为带有“!”的可选变量时,
var optionalSquare: Square! = Square(sideLength: 10, name: "Optional Square")
如果我们想使用 "optionalSquare" 变量,我们不需要打开它因为我们确定(我认为这就是我们使用“!”而不是“?”的原因)它不会包含任何空值。那么我们为什么不将其声明为普通变量呢。
请更正任何不实陈述。谢谢。
what does [
var a:Int
] contains when it's declared
没有。它的值是未定义的。 在赋值之前使用它是编译错误。你可以声明它而不初始化它,但是你不能使用它。
这是 Swift 安全哲学的重要组成部分:在 C 中,您同样可以保留一个未初始化的变量,它的值将是未定义的,但编译器不会(默认情况下)报告如果你使用它会出错。
so why don't we declare it as a normal variable.
我没有理由想到使局部变量成为隐式解包的可选变量。该功能适用于结构或 类 上的 properties ("ivars")。您应该在不可能在对象的 init
中设置 属性 的地方使用它们,但可以肯定的是,在使用对象之前该值将存在。
IBOutlet
s 可能是典型的用例。我发现另一个有用的用途是允许通过调用 init
.
您可以声明一个非可选变量而不对其进行初始化 - 只要您不使用该变量,编译器就不会报错。所以这段代码
var num: Int
不会产生任何错误。但是,如果您在初始化之前引用该变量,编译将失败
var num: Int
print(num)
在前一种情况下没有错误,因为可以推迟初始化。您可以声明一个变量,然后在 100 行之后进行初始化。只要你在初始化之前不引用它,你就可以。
要回答你的第二个问题,可以这样说,在许多情况下,声明和上下文初始化隐式展开的变量没有多大意义:非可选变量更合适。
So, what does the variable in the following line contains when it's declared.
没关系,因为你无论如何都无法访问它。像这样的声明告诉 Swift 您稍后将决定该值。在分配之前读取变量是编译器将要捕获的错误。
why don't we declare [variables with forced unwrapping] it as a normal variables?
因为您可能想在不应该使用它的时候将 nil
存储在该变量中。
例如,您应该使 IB 分配的 属性 隐式展开,因为它们需要 nil
在 NIB 对象 "inflated" 之前,但在 init
之后方法已完成:
@IBOutlet private weak var myLabel: UILabel!
为了使 myLabel
成为非可选的,您必须删除 weak
。另一方面,您不想在每次访问 myLabel
时都使用感叹号,因为您确定它必须被初始化。
同样的推理适用于您希望设为非可选但不能在初始值设定项中赋值的其他变量。