当前位置: 首页 > 面试题库 >

为什么我可以更改/重新分配从类实例化的常量值

公西光华
2023-03-14
问题内容

我创建了以下课程

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

问题答案:

正如@Wain所说的–这是由于引用类型的性质造成的。实例是一个let常量仅意味着您不能为其分配新的引用–但却没有提及实例本身的实际可变性。

如果将类更改为结构,则将看到行为随 _值_类型的不同,因为更改属性会更改您的实际值Person-因此,如果它是let常量,则无法这样做。但是,我有点怀疑您要构建自己Person的结构,因为不应将两个具有相同名称的人视为同一个人。

如果您只希望在初始化时分配属性(然后在实例的生命周期内对其进行只读),则建议您将它们设置为let常量(而不是将其设置器设为私有)。一旦分配,这将确保您甚至无法在班级内更改它们的值。

规则是,只要在super.init()调用之前为属性赋予一个值–您就可以使其成为let常数(在这种情况下,只需在使用之前在初始化程序中分配它们self)即可。

class Person {
    let firstName: String
    let lastName: String

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }

...


 类似资料:
  • 问题内容: 我知道ES6尚未标准化,但是目前许多浏览器都支持 JS中的关键字。 规范中写道: 常量的值不能通过重新分配而更改,并且常量也不能重新声明。因此,尽管可以在不初始化的情况下声明常量,但这样做是没有用的。 当我做这样的事情: 我看到一切正常仍和是。 但是,如果这样做,我的常量数组已更改。现在是这样,顺便说一句,我仍然无法用更改它。 我这是一个错误,还是我错过了什么?我在最新的chrome和

  • 我知道类和抽象类的主要区别是,抽象类不能被实例化, 但是我可以为抽象类创建对象 我用新的关键字创建了抽象的对象 我有一些问题在 Inet 上没有正确的答案, new关键字是否用于实例类? 2)实例只不过是对象吗? 3)mEarth被称为物体(地球的实例)吗? 现在我可以调用任何方法(作为回调或作为值返回)mearth . sand();mearth . land();使用地球物体

  • 为什么可以从子实例访问我的超类的静态方法? 我可以同意从父类的实例访问父类的静态方法。但是如果我实例化一个子类,访问父类的静态上下文会很奇怪。 PS 在实例上调用静态方法的优点是什么?

  • 下面的代码为什么编译? std::move的文档说 执行此操作后,“移动自”范围中的元素仍将包含适当类型的有效值,但不一定与移动前的值相同。 所以这实际上可以改变对象foo2,即使它声明为const。为什么这样做有效?

  • 问题内容: 如果我有一个数字列表,并且想使用for循环将其递增,那为什么不起作用: 我期望得到[2,3,4,5,6]。 我知道我可以通过解决这个问题 但是必须有一种更简单的方法。 问题答案: 这是因为您仅获得列表中变量的引用。替换它时,只需更改该引用指向的内容,因此列表中的项目保持不变。对此的最佳解释是直观地进行跟踪-逐步执行该链接处的执行可视化,并且应该非常清楚。 请注意,可变对象可以在适当位置