在引用类型中,let和var有什么区别?当我们在iOS中以编程方式创建IBOutlet时,Swift有什么不同之处?

11 浏览
0 Comments

在引用类型中,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我知道letvar在变量定义时的区别。对于输出,是否相同?我们如何看到输出中的区别?

0
0 Comments

在Swift中,使用let关键字声明的变量是常量,一旦定义后就无法更改。而使用var关键字声明的变量是可变的,可以在运行时进行更改。

在上述代码中,letvar关键字分别用于声明不同类型的变量。具体来说,let关键字用于声明常量,而var关键字用于声明可变变量。

这两个关键字的使用方式对于代码中的具体属性有着不同的影响。使用let关键字声明的变量是不可变的,一旦定义后就无法更改其值。而使用var关键字声明的变量是可变的,可以在需要时随时更改其值。

这些信息可以在以下链接中找到更详细的解释和示例代码:

github.com/thoughtbot/guides/issues/435

developer.apple.com/library/content/documentation/Swift/…

0
0 Comments

在你的例子中,你考虑了在声明属性本身以及初始化该属性的闭包中使用var还是let。回答你的问题,简而言之,任何可以使用let(常量)的地方,理论上也可以使用var(变量),但只有在计划稍后更改该变量时才应该这样做。对于像UILabel这样的引用类型,这意味着如果你计划用一个全新的UILabel实例替换该标签。

因此,第一种和第四种选项,在闭包中使用了var,可以驳回,因为这是一种不良的编程风格,因为你在闭包的范围内没有再次更改它,所以我们知道应该在闭包中使用let

关于第二种或第三种选项(即属性本身是否应该是常量还是变量),问题是你是否打算稍后将该UILabel替换为另一个。如果是这样,你必须使用第三个选项。但是我们可以怀疑这不太可能是你的意图,所以如果你不打算稍后替换该标签,那么在这四个选项中,你会倾向于使用let/let的第二个选项。


话虽如此,这似乎是在一个视图控制器中,我不建议在实例化视图控制器期间实例化任何视图对象。通常,这是推迟到viewDidLoad或者如果整个视图层次结构是以编程方式构建的,在loadView中进行的。或者,更好的是,我们不再手动构建控件,而是让故事板在适当的时候实例化IBOutlet引用。

是的,我同意你的观点。但是在这里,“关于第二种或第三种选项,问题是你是否打算稍后更改该UILabel”,更改意味着哪种类型的更改。比如更改它的text,或者更改它的backgroundColor或者其他什么?

不,因为UILabel是一个引用类型,这意味着是否将该UILabel替换为一个完全不同的UILabel(这是极不可能的)。如果变量是值类型,任何更改对象的操作都需要var以允许可变性,但我们正在处理引用类型。

好的,明白了。谢谢帮助。

重要的是要理解,使用letvar不会改变所引用对象的可变性;let a=UILabel()仍然允许你更改标签的属性,但你不能更改a,所以a = someOtherLabel是不允许的。同样,var array = NSArray()不允许你更改数组,因为对象本身是不可变的。但是我可以说array = someOtherArray,因为array是一个变量,而不是一个常量。

0