函数被调用但未执行

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()

【讨论】:

以上是关于函数被调用但未执行的主要内容,如果未能解决你的问题,请参考以下文章

Qt 插槽连接成功但未被触发

函数在被执行以前其中的全局变量报错

方法被调用但未执行

Angular Fire Functions 调用但未运行

尽管满足条件(即,字符串值符合预期),但未调用函数

Django Channels - 握手和连接,但未执行 websocket.connect 函数