为什么我可以改变/重新赋值一个从类实例化的常量值 [英] Why I can change/reassigned a constant value that Instantiated from a class
问题描述
我创建了以下类
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
的内容?这不是一个常数吗?有人可以解释一下,对我来说,非常感谢。
Question: Why I can change the content of the variable john
? Isn't it a constant? Can someone explain that for me, thanks a lot.
john.firstName = "John"
print(john.firstName) // -> John
推荐答案
As @Wain说 - 这是由于参考类型的性质。实例是 let
常量只意味着你不能为它分配一个新的引用 - 但是对实例本身的实际可变性一无所知。
As @Wain has said – it's due to the nature of reference types. The instance being a let
constant only means you cannot assign a new reference to it – but says nothing about the actual mutability of the instance itself.
如果您将类更改为结构,您将看到该行为与值类型不同,因为更改属性会更改 Person
- 因此如果它是一个 let
常量,你就不能这样做。但是我有点怀疑,你会想让你的 Person
一个结构,因为两个同名的人不应该被认为是同一个人。
If you change your class to a struct, you'll see how the behaviour differs with value types, as changing a property changes the actual value of your Person
– therefore you are unable to do so if it's a let
constant. However I somewhat doubt you'll want to make your Person
a struct, as two people with the same name shouldn't be considered to be the same person.
如果你只希望你的属性在初始化时分配(然后在实例的生命周期只读),那么我会建议让他们 let
常量(而不是使它们的setter私有)。
If you only wish your properties to be assigned upon initialisation (and then read-only for the lifetime of the instance), then I would recommend making them let
constants (instead of making their setters private). This will ensure that you cannot even change their value from within your class, once assigned.
这个规则只要你给一个属性一个值之前的 super.init()
调用 - 你可以使它成为一个 let
常量(在这种情况下,你只需要在初始化器使用 self
)。
The rule is as long you give a property a value before the super.init()
call – you can make it a let
constant (in this case, you just have to assign them in the initialiser before using self
).
class Person {
let firstName: String
let lastName: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
...
这篇关于为什么我可以改变/重新赋值一个从类实例化的常量值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!