函数被调用但未执行
Posted
技术标签:
【中文标题】函数被调用但未执行【英文标题】:Function being called but not executing 【发布时间】:2017-07-21 07:42:33 【问题描述】:我有这个自定义运算符:
infix operator ?> : NilCoalescingPrecedence
func ?> (lhs: Any?, rhs: @autoclosure ()->Any)
if lhs == nil
print("lhs is nil")
rhs()
用法:
optional ?>
print("executing")
问题是,当lhs
为nil 时,闭包没有执行。在控制台中“lhs is nil”正在打印,但之后没有“执行”正在打印。 “lhs is nil”打印语句如何执行,而不是rhs
?
【问题讨论】:
【参考方案1】:导致此行为的原因是@autoclosure
,如果您删除它,它会正常工作。
这是因为@autoclosure
会将你的闭包包装成一个闭包,所以现在你有这样的东西:
print("executing")
外部闭包返回Any
,对吗?所以它只会返回闭包 print("executing")
而不会做任何其他事情。
如果你想保留@autoclosure
,你可以这样使用操作符:
optional ?> print("executing")
【讨论】:
如果我希望能够做到optional ?> print("executing")
和optional ?> print("executing"); ...
怎么办?
我认为您只需要编写另一个重载。虽然没有测试。 @鞋
这有点多,但我提供了an answer 来演示它【参考方案2】:
解决方案似乎是向具有完全相同签名的运算符添加重载,只是它没有@autoclosure
注释,并且两者的rhs
都必须返回Void
而不是@ 987654324@.
infix operator ?> : NilCoalescingPrecedence
func ?> (lhs: Any?, rhs: @autoclosure ()->Void)
if lhs == nil
print("lhs is nil")
rhs()
func ?> (lhs: Any?, rhs: ()->Void)
if lhs == nil
print("lhs is nil")
rhs()
如果我这样做,就这样:
optional ?> doSomething()
@autoclosure
将被调用,无论 doSomething()
是否返回任何内容。
如果我这样做:
optional ?>
doSomething()
doSomethingElse()
将调用没有@autoclosure
的那个,因为闭包的类型是()->Void
。
【讨论】:
【参考方案3】:您需要在闭包方法的末尾添加()
,如下所示
optional ?>
print("executing")
()
【讨论】:
【参考方案4】:如果您打算在运算符之后添加大括号 ,您可以将其实现(无需将 rhs
声明为自动关闭):
infix operator ?> : NilCoalescingPrecedence
func ?> (lhs: Any?, rhs: ()->Any)
if lhs == nil
print("lhs is nil")
rhs()
var myString: String? = ""
// some case that made "string" to be nil...
myString = nil
myString ?>
print("executing")
但是,声明自动关闭的目的是包装作为参数传递给函数的表达式:
这种语法上的便利让你可以省略函数的大括号 通过编写普通表达式而不是显式的参数 关闭。
The Official Swift Documentation - Closures,自动关闭
这意味着不需要花括号,在使用运算符时应该更自然:
infix operator ?> : NilCoalescingPrecedence
func ?> (lhs: Any?, rhs: @autoclosure ()->Any)
if lhs == nil
print("lhs is nil")
rhs()
var myString: String? = ""
// some case that made "string" to be nil...
myString = nil
// you could use your operator like:
myString ?> print("executing")
等一下!
可能会遇到一个问题:如果要在操作符后面加一段代码怎么办?
好吧,毫无疑问,你必须添加花括号:
let doSomething =
print("executing")
print("second line of execution")
print("third line of execution")
myString ?> doSomething()
【讨论】:
以上是关于函数被调用但未执行的主要内容,如果未能解决你的问题,请参考以下文章