部分应用'变异'方法是不允许的

时间:2016-05-27 16:26:21

标签: swift

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)

3 个答案:

答案 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)