Используйте 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
в качестве типа значения (a 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 Создание лучших приложений с помощью типов значений в Swift.
person
Rob
schedule
15.03.2017