我创建了以下类
class Person {
var firstName: String
var lastName: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
func fullName() -> String {
return "\(firstName) \(lastName)"
}
}
然后我从类
中实例化了一个常量值 let john = Person(firstName: "Johnny", lastName: "Applessed")
问题:为什么我可以更改变量john
的内容?这不是常数吗?有人能为我解释一下,非常感谢。
john.firstName = "John"
print(john.firstName) // -> John
答案 0 :(得分:5)
作为@Wain has said - 这是由于引用类型的性质。实例为let
常量仅表示您无法为其指定新引用 - 但对实例本身的实际可变性没有任何说明。
如果您将类更改为结构,您将看到行为与值类型的不同,因为更改属性会更改Person
的实际值 - 因此您如果它是let
常数,则无法这样做。但是我有点怀疑你是否想让你的Person
成为一个结构,因为两个同名的人不应该被认为是同一个人。
如果您只希望在初始化时分配属性(然后在实例的生命周期内只读),那么我建议将它们设为let
常量(而不是将它们的setter设为私有)。这将确保您在分配后甚至无法从班级中更改其价值。
规则只要您在super.init()
调用之前为属性赋值 - 您可以将其设为let
常量(在这种情况下,您只需在使用前将其分配到初始化器中) self
)。
class Person {
let firstName: String
let lastName: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
...
答案 1 :(得分:3)
类实例本身是一个常量,因此您无法将其更改为引用另一个实例,但该实例是可变的,因为它的属性创建为firstName
。
将private(set) var firstName: String
更改为拥有私人设定器并查看您可以执行的操作:
model
答案 2 :(得分:2)
当您在swift中使用类的常量实例时,并不意味着您无法更改类属性。它'意味着您无法在此常量
中实例化新对象let person = Person(firstName: "Johnny", lastName: "Appleseed")
person = Person(firstName: "John", lastName: "Appleseed") //--->It gets error: Cannor assign to value: 'person' is a 'let' constant
但是你可以在内部类中创建一个常量并在init
中设置这个值class Person {
let firstName: String
let lastName: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
func fullName() -> String {
return "\(firstName) \(lastName)"
}
}
//Tip: Don't init the class constants in declaration time or will get the same above error. Just init this constants at constructor/initialization of class.
现在你得到了你想要的预期结果,即使创造了一个' var'该对象的实例
var person = Person(firstName: "Johnny", lastName: "Appleseed")
person.firstName = "John" //--->It gets error: Cannor assign to value: 'person' is a 'let' constant
person = Person(firstName: "John", lastName: "Snow")
person.firstName = "Johnny" //--->It gets error: Cannor assign to value: 'person' is a 'let' constant
你的想法并没有错,但有点混乱,因为如果它是一个结构而不是一个类,你就完全正确。