【问题标题】:Why is constant instance of a value type can NOT change its properties while constant instance of a reference type can?为什么值类型的常量实例不能更改其属性,而引用类型的常量实例可以?
【发布时间】:2016-02-26 21:06:59
【问题描述】:

我是 Swift 新手,正在尝试学习属性的概念。我从“swift编程语言2.1”中看到了下面的语句和代码。

struct FixedLengthRange {
    var firstvalue: Int
    let length: Int
}

let rangeOfFourItems = FixedLengthRange(firstvalue: 0, length: 4)
rangeOfFourItems.firstvalue = 8 //error: cannot assign to property: rangeOfFourItems is a "let" constant

并且书中对错误提供了以下解释:

这种行为是由于结构是值类型。当一个实例 值类型的 被标记为常量,它的所有属性也是如此。

对于作为引用类型的类而言,情况并非如此。如果你 将引用类型的实例分配给常量,您仍然可以 更改该实例的变量属性。

为什么值类型的常量实例不能改变其属性,而引用类型的常量实例可以?背后的原因是什么?这本书确实说明了原因,但未能解释原因。我认为了解事物现状背后的原因是一种很好的做法。谁能给我解释一下?

【问题讨论】:

    标签: swift reference constants


    【解决方案1】:

    为什么值类型的常量实例不能改变它的属性

    因为值类型被视为不可分割的单元:它在赋值时被复制,将其作为参数传递就像复制一样,因此使用 const-ness 会锁定整个 struct。从某种意义上说,rangeOfFourItems 变量代表结构本身,而不是指针或对它的引用。

    而引用类型的常量实例可以吗?

    说声明引用类型的 const 变量也会使实例成为常量,这并不完全正确。只有引用是常量,而不是实例。

    如果你仔细想想,这是唯一可以有意义地实现的方法,因为多个变量可以引用同一个引用实例。如果其中一个变量是常量而另一个不是常量,则将非常量引用分配给常量变量不可能锁定被引用的对象,这也会锁定非常量引用:

    var a = ByRefType()
    let b = a; // b is a constant reference to the same instance as "a"
    a.property = newValue; // Prohibiting this assignment would be inconsistent
    

    与非常量变量a不同,常量变量本身(例如上面的b)当然不能重新赋值。

    【讨论】:

    • 对值类型实例的常量引用意味着引用本身不能更改为指向任何其他值类型实例,它不应该影响值类型本身或其属性,如果我理解正确。那么为什么这会使值类型的属性也不可变呢?不可能有其他对这个特定值类型的引用。
    • 非常感谢您的详细解释!
    猜你喜欢
    • 2016-10-26
    • 2020-11-30
    • 1970-01-01
    • 2020-04-07
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多