如何在不使用try/catch的情况下传递Swift的||运算符作为参数?
Swift中如何将||运算符作为参数传递(不处理try/catch)
首先是原始的简单Swift代码:
func f(_ a: Bool, _ b: Bool) { print(a || b) } f(false, false)
尝试将运算操作作为参数传递,编写了如下代码:
func g(_ a: Bool, _ b: Bool, _ op: (Bool, Bool) -> Bool) { print(op(a, b)) } g(false, false, ||)
但||运算符并非想象中简单,出现错误:
error: cannot convert value of type '(Bool, @autoclosure () throws -> Bool) throws -> Bool' to expected argument type '(Bool, Bool) -> Bool'
尝试修改函数g的参数类型为:
func g(_ a: Bool, _ b: Bool, _ op: (Bool, @autoclosure () throws -> Bool) throws -> Bool) { print(op(a, b)) } g(false, false, ||)
又出现错误:
error: call can throw, but it is not marked with 'try' and the error is not handled
请问如何才能在不处理try/catch的情况下将||作为参数传递?
解决方案
Swift的||运算符为实现短路求值,第二个参数被标记为@autoclosure,同时类型声明带有throws(尽管实际不会抛出错误),这导致直接传递时出现类型不匹配和抛出检查问题。可以通过以下两种方式解决:
方式1:用闭包包装||
将||包裹在普通闭包里,适配成(Bool, Bool) -> Bool类型,避开@autoclosure和throws特性:
func g(_ a: Bool, _ b: Bool, _ op: (Bool, Bool) -> Bool) { print(op(a, b)) } // 用闭包包装运算符 g(false, false, { $0 || $1 }) // 或者使用更简洁的尾随闭包写法 g(false, false) { $0 || $1 }
方式2:适配运算符类型并强制忽略抛出
如果想直接传递||,可以修改函数参数类型匹配运算符的原始签名,同时用try!强制忽略抛出检查(||实际运行中不会抛出任何错误,该操作安全):
func g(_ a: Bool, _ b: Bool, _ op: (Bool, @autoclosure () throws -> Bool) throws -> Bool) { print(try! op(a, b)) } g(false, false, ||)
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

