在以下情况下使用let:
- 它是一个常量(或者对于像
class 这样的引用类型,如果引用不能被另一个引用替换);和
- 您可以在初始化过程中进行设置。
但是如果你以后需要能够改变它,使用var,比如值不是常量的真变量(或者在引用类型的情况下,如果你需要用另一个实例替换它)。但是在初始化过程中没有设置值的变量和属性,你必须使用var。例如,lazy 存储属性使用var,因为它们的值在初始化过程完成时没有设置,而只有在您第一次引用它时才设置。另一个示例包括视图控制器对其出口的引用,这些出口仅在稍后创建视图层次结构时才连接。
不用说,计算属性也使用var。
但是,如果你可以使用let,你应该这样做,因为如果你知道什么是常量,什么是变量,那么编写安全代码会更容易。在您的示例中,您将使用let。
注意:对于引用类型,如class 类型,let 并不意味着对象本身一定是不可变的,只是不能用另一个实例替换它。如果您想控制它是否不可变,请考虑使用值类型(例如 struct)。
让我看看能否让最后的注释更清楚。考虑:
class Foo {
var value: String
init(value: String) {
self.value = value
}
}
那么以下是允许的:
let obj = Foo(value: "a")
obj.value = "b" // changing mutable property of reference type, Foo, is permitted
但以下不是:
let obj = Foo(value: "a")
obj = Foo(value: "b") // replacing `obj` with a new instance of `Foo`, is not
如果您不想更改 value 属性,您可以将 value 定义为不可变(或至少不公开可变),例如:
class Foo {
let value: String // or `private(set) var value: String`
init(value: String) {
self.value = value
}
}
或者不要将Foo 定义为class(引用类型),而是将其定义为struct(值类型):
struct Foo {
var value: String
init(value: String) {
self.value = value
}
}
let obj = Foo(value: "a")
obj.value = "b" // this is not permitted, because Foo value-type, `obj`, was declared with `let`, making it immutable
请注意,最后一个示例,将 Foo 声明为值类型(struct)确实从根本上改变了它,例如
var obj1 = Foo(value: "a")
var obj2 = obj1 // this value is a copy of `obj1` not a reference to the same object that `obj1` pointed to
obj1.value = "b"
print("\(obj1.value)") // will print "b"
print("\(obj2.value)") // will print "a"
但是值类型虽然需要稍微不同的思维方式来使用它们,但对于轻松编写安全代码非常有用。请参阅 WWDC 2015 Building Better Apps with Value Types in Swift。