Swift中的var和let有什么区别?

4

我是Swift编程的新手,遇到了varlet类型。我知道let是一个常量并且知道它的含义,但我从未使用过常量,因为我没有必要。那么,在什么情况下应该使用var而不是let呢?


尽可能使用 let,因为编译器可以更好地进行优化。 - Daniel Bo
常量是为了方便阅读和帮助编译器进行优化而存在的(两者的原因相同:更容易推理一个永远不会改变值的变量,这使得可能的代码分支要小得多)。然而,我不会仅仅因为编译器的优化就到处使用常量。过早的优化等等...我会在变量永远不需要改变其值时使用它来提高自己的可读性。有时候,你可以稍微重写你的代码,只需要给一个变量赋值一次,这样你就可以把它变成一个let(但如果这样做不够可读,就不要这样做!) - Millie Smith
@AlexK,这个问题更多关于设计原则。你提供的链接更多关于语义学。 - Millie Smith
3个回答

20
与其用"constant"和"variable"这样的词汇,Swift中正确的术语应该是"immutable"(不可变)和"mutable"(可变)。
当你知道一旦给变量赋值后它就不会再改变时,你应该使用"let"来声明它是不可变的。比如,如果你声明了一个表视图单元格的id,那么在它的生命周期内它很可能不会改变,因此通过将其声明为不可变,就没有风险会错误地更改它——编译器会提示你。
典型的用例包括:
- 常量(定时器超时时间、固定大小标签的宽度、登录尝试的最大次数等)。在这种情况下,常量是分散在代码中的字面值的替代品(可以想象成"#define")。 - 函数的返回值作为另一个函数的输入 - 表达式的中间结果,作为另一个表达式的输入 - 可选绑定中未包装值的容器 - 由REST API调用返回的数据,从JSON反序列化为结构体,并存储在数据库中
每次我写"var"时,我都会问自己:"这个变量能改变吗?"。如果答案是否定的,我会用"let"来替换"var"。有时我也会采取更保护性的方法:我把所有东西都声明为不可变的,然后编译器会在我尝试修改其中一个时让我知道,针对每种情况我可以采取相应的措施。
一些注意事项:
对于引用类型(类),不可变意味着一旦将实例分配给不可变变量,就不能再将另一个实例分配给同一个变量。

对于值类型(数字、字符串、数组、字典、结构体、枚举),不可变意味着一旦你分配了一个值,你就不能再更改该值本身。对于简单数据类型(IntFloatString),这意味着你不能分配相同类型的另一个值。对于复合数据类型(结构体、数组、字典),它意味着你不能分配一个新值(如结构体的新实例)并且 你不能更改它们存储的任何属性。

此外,对于开发人员和阅读代码的人来说,不可变变量具有语义上的含义 - 它清楚地表示变量不会更改。

最后,但从纯开发角度来看可能不太重要的是,编译器可以对不可变对象进行优化。


5

一般来说,尽可能避免使用可变状态。

不可变值有助于推理代码,因为您可以轻松追踪并清晰地识别该值从开始到结束的情况。

另一方面,可变变量使得数据流难以跟踪,因为任何人都可以随时修改它们。特别是在处理并发应用程序时,推理可变状态可能很快变得非常困难。

因此,作为设计原则,尽可能使用let,如果需要修改对象,则仅生成新实例。

每当需要使用var时,可能是因为使用它可以使代码更清晰,请尽可能限制它们的范围,并且不要暴露任何可变状态。例如,如果在函数内部声明一个var,只要不向调用者公开该可变性,就可以这样做,即从调用者的角度来看,它不应该关心您在实现中使用了var还是val


我会点赞这个答案,因为我认为它比其他两个答案好得多(楼主显然理解语义,而你则触及了可读性)。但是,我不认为它应该被广泛使用。如果尽可能编写尽可能多的不可变代码,它可能会使函数变得冗长、丑陋和繁琐。有时候变量可以让代码更清晰。它们应该根据具体情况使用。 - Millie Smith
@MillieSmith,我理解你的观点。在我看来,可变性应该是一个例外。然而,在代码中加入一些变量并不会对任何人造成伤害,只要可变状态没有被暴露出来。我会更新我的答案。 - Gabriele Petronella

0
一般来说,如果你知道一个变量的值不会改变,就将其声明为常量。不可变的变量会使你的代码更易读,因为你可以确定特定的变量永远不会被改变。这对编译器也可能更好,因为它可以利用变量是常量的事实并执行一些优化。
这不仅适用于Swift。即使在C中,当变量的值在初始化后不会被改变时,确保它是const是一个好习惯。
所以,你应该改变对“我不需要”的看法。你不仅需要像TIMEOUT等值的常量,你还应该在任何你知道变量的值在初始化后不需要改变的地方使用常量变量。
注意:这更多是一个关于“整个编程”而不是Swift特定的答案。@Antonio的答案更专注于Swift。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接