'let'是如何实现的?

How is 'let' implemented?

我直接从 this Apple 页面

中提取了这个示例
struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}

并且如果您将此结构的实例分配给常量,

let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)

它说我们无法更改它的 属性 值,即使它被声明为 'var'

这让我想知道 let 是如何实现的?我希望可以在编译时检测到对它的任何分配并显示编译错误。但是在上面的例子中,为什么它适用于结构的每个 属性,不管它是如何定义的?

我试着搜索这个,发现很难用关键字 'let' 搜索,因为它是很常见的术语。

谁能帮我理解一下?

这是因为结构是值类型。这意味着它不能就地改变。

因此,如果我们有一个变量 rangeOfFourItems 是 FixedLengthRange 结构实例,并且我们想要设置 rangeOfFourItems.firstValue,我们实际上是从 [=11= 中提取结构实例] 存储和替换它与另一个具有不同firstValue.

的结构实例

要证明这是真的,用 var 声明 rangeOfFourItems 并附加一个 setter 观察者,然后更改 rangeOfFourItems.firstValue:

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}
var rangeOfFourItems = FixedLengthRange(firstValue:1, length:4) {
    didSet {
        print("Hey, you set me!")
    }
}
rangeOfFourItems.firstValue = 2 // Hey, you set me!

这表明仅设置此结构实例的 属性 实际上设置了结构变量本身。

但是在你的代码中,我们不能那样做,因为rangeOfFourItems阻止了这种隐式赋值——它是用let声明的,这意味着它必须保留一个常数。因此,在编译器级别阻止设置 rangeOfFourItems.firstValue

(如果 FixedLengthRange 是 class 而不是结构,它将是 引用类型 ,并且将是可变的,即使 rangeOfFourItems 是用 let 声明的,设置 rangeOfFourItems.firstValue 也是合法的。)