我有一个使用@autoclosure的函数。有没有办法让 @autoclosure 的行为与重载函数类似,这样它就会自动知道哪种语法适合像我这样的变量?
func myEnvironment(_ bindings: @autoclosure () -> [Int], _ body: ([Int]) -> Int) -> Int {
let vars = bindings()
return body(vars)
}
// prints 4
let result = myEnvironment([]) { _ in
2 + 2
}
// Error
// prints 6
let result2 = myEnvironment {
let x = 1
let y = 2
let z = 3
return [x, y, z]
} _: { vars in
vars[0] + vars[1] + vars[2]
}
错误
// prints 6
let result2 = myEnvironment {
let x = 1
let y = 2
let z = 3
return [x, y, z]
} _: { vars in
vars[0] + vars[1] + vars[2]
}
error 1:
Contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored
error 2:
Cannot convert value of type '[Int]' to closure result type 'Int'
有没有办法实现所需的行为,或者我需要修改我的代码吗?
我看到这篇文章How to use Swift @autoclosure但它没有回答我的问题。如有任何建议,我们将不胜感激。
我假设您还希望允许调用者传入包含多行代码的代码块作为自动闭包。
您可以声明另一个不带
@autoclosure
的重载。
// The '@autolcosure' overload can delegate to the new overload:
func myEnvironment(_ bindings: @autoclosure () -> [Int], _ body: ([Int]) -> Int) -> Int {
myEnvironment(bindings, body)
}
func myEnvironment(_ bindings: () -> [Int], _ body: ([Int]) -> Int) -> Int {
let vars = bindings()
return body(vars)
}
// ------------
// or the other way around!
func myEnvironment(_ bindings: () -> [Int], _ body: ([Int]) -> Int) -> Int {
myEnvironment(bindings(), body)
}
func myEnvironment(_ bindings: @autoclosure () -> [Int], _ body: ([Int]) -> Int) -> Int {
let vars = bindings()
return body(vars)
}
如果由于某种原因无法添加重载,则可以传递“立即调用”闭包。由于
@autoclosure
,这个闭包实际上并没有立即被调用。
myEnvironment({
let x = 1
let y = 2
let z = 3
return [x, y, z]
}()) { x in
vars[0] + vars[1] + vars[2]
}