Mutable 和 Modifialbe 它们的含义是什么?
Mutable and Modifialbe what is the meaning of them?
让我们从一些代码段开始
struct DigitS {
var number = 42
init(_ n: Int) {
self.number = n
}
mutating func replace() {
self = DigitS(12) // mutating
}
}
class DigitC {
var number = 42
init(_ n: Int) {
self.number = n
}
func replace() {
self = DigitC(12) //#Cannot assign to value: "self" is immutable
}
}
很长一段时间,我对mutable、modifiable的含义很困惑。以上是我目前的一些理解,如果能指出其中可能存在的错误就更好了
上述结构类型中的变异函数没有"mutates"实例,它将用一个全新的值替换变量的旧值
变异意味着:赋值、初始化或变异函数等动作不会修改当前值,但会触发替换
一个 class 类型变量的值是不可变的,但你可以 modify/change 当前值(这是编译器发出警告的原因,请参阅注释#)
setter观察者,只能在类型为值类型时调用,因为setter告诉变量是否已经mutated/replaced(请看下面的代码)
struct Digit {
var number = 12
}
var b = Digit() {
didSet{ print("number is set") }
}
b.number = 22 // observer is called
class Digit {
var number = 12
}
var b = Digit() {
didSet{ print("number is set") }
}
b.number = 22 // observer is not called
感谢您的宝贵时间和帮助
使用图像可以更好地解释内存处理,但我会在这里试一试:
- 你说的有点对,它实际上是在改变存储在变量位置的数据。
给定一个带有修改器的简单结构:
struct Example {
var text: String
mutating func changeText(to newText: String) {
self.text = newText
}
}
let constantExample = Example(text: "Test") //Makes a section of memory that isn't allowed to change.
constantExample.changeText(to: "Other Test") //This doesn't work because constantExample isn't mutable.
var mutableExample = Example(text: "Test") //Makes a section of memory that is allowed to change.
mutableExample.changeText(to: "Other Test") //This doesn't make a new copy, but rather changes the value in mutableExample's section of memory
如果您要使用您提到的特定案例:
mutating func changeText(to newText: String) {
self = Example(text: "A new text")
}
mutableExample 仍将驻留在相同的内存位置,但您正在手动创建 Example 的全新实例,然后将该实例中的数据复制到 mutableExample。
相反 :) 变异就地改变了实例。您可以通过复制不同的值来更改该实例(如 self =
示例中所发生的那样),但该实例仍然是同一个实例,只是具有不同的值。
创建 class 变量时,您正在创建对一段内存的 引用。设置或更改该引用 var variableName = classInstance
时,引用的位置在初始化后保持不变,但被引用的位置(如果是 var)随后可以更改。
您在功能上是正确的,但缺少一些细微差别。在结构示例中,如前所述,实例的实际值正在发生变化。在 class 示例中,引用的内存在变化,但存储在 b
中的实际值没有变化。
观察者观察值的变化,class类型变量的值是指向对象的引用。要触发 属性 观察器,必须更改引用。
class Digit {
var number = 12
}
var a = Digit()
var b = Digit() {
didSet{ print("number is set") }
}
b.number = 22 // observer is called
b = a //observer is called here!!
让我们从一些代码段开始
struct DigitS {
var number = 42
init(_ n: Int) {
self.number = n
}
mutating func replace() {
self = DigitS(12) // mutating
}
}
class DigitC {
var number = 42
init(_ n: Int) {
self.number = n
}
func replace() {
self = DigitC(12) //#Cannot assign to value: "self" is immutable
}
}
很长一段时间,我对mutable、modifiable的含义很困惑。以上是我目前的一些理解,如果能指出其中可能存在的错误就更好了
上述结构类型中的变异函数没有"mutates"实例,它将用一个全新的值替换变量的旧值
变异意味着:赋值、初始化或变异函数等动作不会修改当前值,但会触发替换
一个 class 类型变量的值是不可变的,但你可以 modify/change 当前值(这是编译器发出警告的原因,请参阅注释#)
setter观察者,只能在类型为值类型时调用,因为setter告诉变量是否已经mutated/replaced(请看下面的代码)
struct Digit { var number = 12 } var b = Digit() { didSet{ print("number is set") } } b.number = 22 // observer is called class Digit { var number = 12 } var b = Digit() { didSet{ print("number is set") } } b.number = 22 // observer is not called
感谢您的宝贵时间和帮助
使用图像可以更好地解释内存处理,但我会在这里试一试:
- 你说的有点对,它实际上是在改变存储在变量位置的数据。
给定一个带有修改器的简单结构:
struct Example {
var text: String
mutating func changeText(to newText: String) {
self.text = newText
}
}
let constantExample = Example(text: "Test") //Makes a section of memory that isn't allowed to change.
constantExample.changeText(to: "Other Test") //This doesn't work because constantExample isn't mutable.
var mutableExample = Example(text: "Test") //Makes a section of memory that is allowed to change.
mutableExample.changeText(to: "Other Test") //This doesn't make a new copy, but rather changes the value in mutableExample's section of memory
如果您要使用您提到的特定案例:
mutating func changeText(to newText: String) {
self = Example(text: "A new text")
}
mutableExample 仍将驻留在相同的内存位置,但您正在手动创建 Example 的全新实例,然后将该实例中的数据复制到 mutableExample。
相反 :) 变异就地改变了实例。您可以通过复制不同的值来更改该实例(如
self =
示例中所发生的那样),但该实例仍然是同一个实例,只是具有不同的值。创建 class 变量时,您正在创建对一段内存的 引用。设置或更改该引用
var variableName = classInstance
时,引用的位置在初始化后保持不变,但被引用的位置(如果是 var)随后可以更改。您在功能上是正确的,但缺少一些细微差别。在结构示例中,如前所述,实例的实际值正在发生变化。在 class 示例中,引用的内存在变化,但存储在
b
中的实际值没有变化。
观察者观察值的变化,class类型变量的值是指向对象的引用。要触发 属性 观察器,必须更改引用。
class Digit {
var number = 12
}
var a = Digit()
var b = Digit() {
didSet{ print("number is set") }
}
b.number = 22 // observer is called
b = a //observer is called here!!