函数被调用但不执行

Function being called but not executing

我有这个自定义运算符:

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" 正在打印,但之后没有 "executing" 正在打印。 "lhs is nil" print 语句是如何执行的,但不执行 rhs?

您需要在闭包方法末尾添加(),如下所示

optional ?> {
    print("executing")
}()

导致此行为的原因是 @autoclosure,如果您删除它,它会正常工作。

这是因为 @autoclosure 会将你的闭包包装成一个闭包,所以现在你有这样的东西:

{ { print("executing") } }

外层闭包returns Any,对吧?所以它只会 return 闭包 { print("executing") } 并且什么都不做。

如果你想保留@autoclosure,你可以这样使用运算符:

optional ?> print("executing")

如果您打算在运算符之后添加花括号 ,您可以将其实现(无需将 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")
}

但是,声明自动闭包的目的是包装作为参数传递给函数的表达式:

This syntactic convenience lets you omit braces around a function’s parameter by writing a normal expression instead of an explicit closure.

The Official Swift Documentation - Closures, Autoclosures

这意味着不需要花括号,这在使用运算符时应该更自然:

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

解决方案似乎是向具有完全相同签名的运算符添加重载,只是它没有 @autoclosure 注释,并且两者的 rhs 都必须 return Void 而不是 Any.

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

无论 doSomething() return 有没有任何事情,@autoclosure 都会被召唤。

如果我这样做:

optional ?> {
    doSomething()
    doSomethingElse()
}

没有 @autoclosure 的闭包将被调用,因为闭包的类型是 ()->Void.