struct MyStruct {
var count = 0
mutating func add(amount: Int) {
count += amount
}
}
var myStruct = MyStruct()
[1, 2, 3, 4].forEach(myStruct.add)
// Partial application of 'mutating' method is not allowed
为什么不像这样使用forEach
允许变异方法?我知道我能做到
for number in [1, 2, 3, 4] {
myStruct.add(number)
}
或
[1, 2, 3, 4].forEach { myStruct.add($0) }
相反,但都不像
那样干净[1, 2, 3, 4].forEach(myStruct.add)
答案 0 :(得分:16)
值类型的关键是赋值创建副本。此合同还会影响人们如何推理其代码。例如,如果您将Int
传递给方法,则可以确信该值不会从您下方更改,即使传入的原始int被发送到另一个线程并且已完成计算别处。
结构也是如此。这就是为什么在快速定义可能改变'self'的方法时,如果它是一个值类型,你必须将它定义为'mutating'。这说明它会同时用新值重新分配给你的变量。例如,当您使用“3”调用add方法时,您可以将其视为执行类似于:
的操作var myStruct = MyStruct()
var tmp = myStruct
tmp.count = tmp.count + 3
myStruct = tmp
现在您遇到错误的原因是因为部分应用变异函数会破坏该合同。如果您能够保存let myStructAdd = myStruct.add
之类的闭包,那么稍后您可以调用myStructAdd(3)
,它会尝试更改myStruct。这将为值类型提供引用语义,因为现在您可以在以后更改myStruct,即使是使用不同的方法。
简而言之,swift通过为代码可读性提供“变异”方法为您提供了便利,但需要注意的是它必须同时发生,以免破坏值类型契约。
答案 1 :(得分:-1)
struct MyStruct {
static var count = 0
var amount: Int
mutating func add() {
MyStruct.count = MyStruct.count + amount
}
}
var array = [1,2,3,4,5,6]
for i in array {
var callfunc = MyStruct(amount: i)
callfunc.add()
}
print(MyStruct.count) // count of list
您也可以在struct
中使用static var来完成此操作答案 2 :(得分:-1)
这个答案只与错误信息有关,与问题中的代码无关。
我像这样附加到一个数组:
array.append[newElement]
这让我犯了两个错误:
<块引用>不允许部分应用'mutating'方法
'(__owned Int) -> ()' 类型的值没有下标
我收到错误消息,因为我必须使用 ()
而不是 []
。基本上第一个错误是误导跟随。修复第二个错误消息,解决了所有问题
将其更改为:后错误消失了:
array.append(newElement)