在引用类型中,let和var有什么区别?当我们在iOS中以编程方式创建IBOutlet时,Swift有什么不同之处?
在引用类型中,let和var有什么区别?当我们在iOS中以编程方式创建IBOutlet时,Swift有什么不同之处?
我们可以通过以下的方式在Swift中以编程的方式定义和设置约束。我用四种不同的方式创建了四个标签输出。如下所示:\nvar labelone : UILabel = {\n var label = UILabel()\n label.text = \"Stack\"\n label.translatesAutoresizingMaskIntoConstraints = false\n return label\n}()\nlet labeltwo : UILabel = {\n let label = UILabel()\n label.text = \"Overflow\"\n label.translatesAutoresizingMaskIntoConstraints = false\n return label\n}()\nvar labelthree : UILabel = {\n let label = UILabel()\n label.text = \"Confused\"\n label.translatesAutoresizingMaskIntoConstraints = false\n return label\n}()\nlet labelfour: UILabel = {\n var label = UILabel()\n label.text = \"More confused\"\n label.translatesAutoresizingMaskIntoConstraints = false\n return label\n}()\nfunc addconstaraints() {\n labelone.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true\n labelone.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true\n labelone.topAnchor.constraint(equalTo: view.topAnchor).isActive = true\n \n labeltwo.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true\n labeltwo.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true\n labeltwo.topAnchor.constraint(equalTo: labelone.bottomAnchor).isActive = true\n \n labelthree.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true\n labelthree.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true\n labelthree.topAnchor.constraint(equalTo: labeltwo.bottomAnchor).isActive = true\n \n labelfour.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true\n labelfour.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true\n labelfour.topAnchor.constraint(equalTo: labelthree.bottomAnchor).isActive = true\n}\n
\n所有都正常工作。是否有任何区别。希望您能帮助我理解这个。\n我知道let
和var
在变量定义时的区别。对于输出,是否相同?我们如何看到输出中的区别?
在Swift中,使用let
关键字声明的变量是常量,一旦定义后就无法更改。而使用var
关键字声明的变量是可变的,可以在运行时进行更改。
在上述代码中,let
和var
关键字分别用于声明不同类型的变量。具体来说,let
关键字用于声明常量,而var
关键字用于声明可变变量。
这两个关键字的使用方式对于代码中的具体属性有着不同的影响。使用let
关键字声明的变量是不可变的,一旦定义后就无法更改其值。而使用var
关键字声明的变量是可变的,可以在需要时随时更改其值。
这些信息可以在以下链接中找到更详细的解释和示例代码:
在你的例子中,你考虑了在声明属性本身以及初始化该属性的闭包中使用var
还是let
。回答你的问题,简而言之,任何可以使用let
(常量)的地方,理论上也可以使用var
(变量),但只有在计划稍后更改该变量时才应该这样做。对于像UILabel
这样的引用类型,这意味着如果你计划用一个全新的UILabel
实例替换该标签。
因此,第一种和第四种选项,在闭包中使用了var
,可以驳回,因为这是一种不良的编程风格,因为你在闭包的范围内没有再次更改它,所以我们知道应该在闭包中使用let
。
关于第二种或第三种选项(即属性本身是否应该是常量还是变量),问题是你是否打算稍后将该UILabel
替换为另一个。如果是这样,你必须使用第三个选项。但是我们可以怀疑这不太可能是你的意图,所以如果你不打算稍后替换该标签,那么在这四个选项中,你会倾向于使用let
/let
的第二个选项。
话虽如此,这似乎是在一个视图控制器中,我不建议在实例化视图控制器期间实例化任何视图对象。通常,这是推迟到viewDidLoad
或者如果整个视图层次结构是以编程方式构建的,在loadView
中进行的。或者,更好的是,我们不再手动构建控件,而是让故事板在适当的时候实例化IBOutlet
引用。
是的,我同意你的观点。但是在这里,“关于第二种或第三种选项,问题是你是否打算稍后更改该UILabel
”,更改意味着哪种类型的更改。比如更改它的text
,或者更改它的backgroundColor
或者其他什么?
不,因为UILabel
是一个引用类型,这意味着是否将该UILabel
替换为一个完全不同的UILabel
(这是极不可能的)。如果变量是值类型,任何更改对象的操作都需要var
以允许可变性,但我们正在处理引用类型。
好的,明白了。谢谢帮助。
重要的是要理解,使用let
或var
不会改变所引用对象的可变性;let a=UILabel()
仍然允许你更改标签的属性,但你不能更改a
,所以a = someOtherLabel
是不允许的。同样,var array = NSArray()
不允许你更改数组,因为对象本身是不可变的。但是我可以说array = someOtherArray
,因为array
是一个变量,而不是一个常量。