使用枚举实现Stack时,init传push给forEach为何报Escaping autoclosure错误?
枚举实现Stack时的闭包捕获问题
问题场景
我用枚举实现了一个简化版的Stack:
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) } }
但在init方法中遇到了如下错误:
Escaping autoclosure captures 'inout' parameter 'self'
我无法理解报错原因——self是值类型,且forEach的闭包并非逃逸闭包。不过当我改成显式调用方法的形式时,错误就消失了:
elements.reversed().forEach { push(element: $0) }
原因解析
问题出在mutating方法引用的隐式转换规则上:
- 当直接把
push这个mutating方法传给forEach时,Swift会自动将其包装成一个自动闭包(autoclosure),并且这个闭包会被标记为逃逸(escaping)。因为mutating方法需要捕获inout self,这种情况下自动闭包的逃逸特性就会触发错误。 - 而显式编写闭包
{ push(element: $0) }时,这是一个普通的非逃逸闭包,它对值类型self的捕获是常规的按值捕获,不会触发逃逸闭包的限制,因此不会报错。
内容的提问来源于stack exchange,提问作者Ozgur Vatansever
相关产品推荐
相关产品推荐

