英文:
Escaping autoclosure captures 'inout' parameter 'self'
问题
我一直在使用枚举类型编写一个简化版的堆栈:
public enum Stack<Element> {
case empty
indirect case node(value: Element, next: Stack<Element>)
public init(_ elements: Element...) {
self = .empty
elements.reversed().forEach(push)
}
public mutating func push(element: Element) {
self = .node(value: element, next: self)
}
}
然而,在初始化器处我遇到了以下错误,并且无法理解,因为 `self` 是一个值类型,而 `forEach` 的主体不是逃逸闭包:
> 逃逸自动闭包捕获了 `inout` 参数 `self`
当我在主体内明确地编写该方法时,就不再出现上述错误。
elements.reversed().forEach { push(element: $0) }
你能帮我理解为什么吗?
英文:
I've been writing a simplified version of Stack using enum types:
public enum Stack<Element> {
case empty
indirect case node(value: Element, next: Stack<Element>)
public init(_ elements: Element...) {
self = .empty
elements.reversed().forEach(push)
}
public mutating func push(element: Element) {
self = .node(value: element, next: self)
}
}
However, I got stuck receiving the below error at initializer and couldn't figure out why since self
is a value type and forEach's body is not an escaping closure:
> Escaping autoclosure captures 'inout' parameter 'self'
When I explicitly write the method inside the body, the error in question is gone.
elements.reversed().forEach { push(element: $0) }
Can you help me understand why?
答案1
得分: 2
这实际上与臭名昭著的“闭包无法隐式捕获可变 self 参数”错误是一样的,只是以另一种方式呈现。这是因为push
是mutating
的结果。
通过替换一个虚假示例很容易确认这一点:
public init(_ elements: Element...) {
self = .empty
elements.reversed().forEach(push)
}
public func push(element: Element) {
}
唯一的区别是我们去掉了关键字mutating
。
英文:
This is actually the same as the infamous "closure cannot implicitly capture a mutating self parameter" error in another guise. It is a consequence of the fact that push
is mutating
.
It is easy to confirm this by substituting a fake example:
public init(_ elements: Element...) {
self = .empty
elements.reversed().forEach(push)
}
public func push(element: Element) {
}
The only difference is that we took away the keyword mutating
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论