swift - 优先级高于闭包

标签 swift

我试图在 Swift 中定义一个优先级高于闭包的自定义运算符。特别是,我希望能够写:

foo --> bar { 
    //... 
}

--> 运算符返回一个函数,该函数将类型为 () -> Void 的闭包作为唯一参数。

但是,我只能得到

(foo --> bar) { 
    //... 
} 

工作。是否有运算符优先级可以使这项工作无需括号?

这是

的优先组
precedencegroup LongArrowPrecedence {
    associativity: left
    higherThan: AssignmentPrecedence
}

infix operator --> : LongArrowPrecedence

谢谢!

最佳答案

我们首先建立一个完整的可验证的例子:

precedencegroup LongArrowPrecedence {
    associativity: left
    higherThan: AssignmentPrecedence
}

infix operator --> : LongArrowPrecedence

func -->(lhs: Int, rhs: Int) -> (() -> ()) -> () {
    return { print(lhs+rhs, terminator: ""); $0() }
}

除了使用此运算符的包含括号的有效调用示异常(exception),紧接着调用 --> 返回的闭包

let foo = 1
let bar = 2

// OK
(foo --> bar) { 
    print(" is the magic number")
} // 3 is the magic number

// OK
((-->)(foo, bar)) { 
    print(" is the magic number")
} // 3 is the magic number

这并不能告诉我们太多,但如果我们研究以下失败案例

// ERROR: cannot call value of non-function type 'Int'
foo --> bar { 
    print(" is the magic number")
} // 3 is the magic number

// ... equivalent to
// ERROR: cannot call value of non-function type 'Int'
foo --> bar({ 
    print(" is the magic number")
}) // 3 is the magic number

我们意识到这里的问题不是“优先级低于闭包”,而是function-call-argument-clause (任何后缀表达式后面的一组括号)将尝试对该后缀表达式进行调用,就好像后缀表达式是一个方法/函数/闭包一样。如果后缀表达式不可调用,或者函数调用参数子句中的调用不匹配可调用的任何重载,则编译器将产生错误。

42()           // ERROR: cannot call value of non-function type 'Int'
let foo = 42
foo()          // ERROR: cannot call value of non-function type 'Int'

func bar() {}  // ERROR: argument passed to call that takes no arguments
bar(42)

因此,提供给从 --> 返回的闭包的尾随闭包在这里不相关:它只是返回闭包的一个参数,而关键问题是 Swift 将应用一个函数- call-argument-clause 到紧接在子句之前的后缀表达式。在您的示例中, bar 构成该后缀表达式,并且只有当您将 foo --> bar 包裹在括号中时,组合的包裹表达式才构成后缀表达式,以下应用函数调用参数子句。

Postfix Expressions

Postfix expressions are formed by applying a postfix operator or other postfix syntax to an expression. Syntactically, every primary expression is also a postfix expression.

Primary Expressions

Primary expressions are the most basic kind of expression. They can be used as expressions on their own, and they can be combined with other tokens to make prefix expressions, binary expressions, and postfix expressions.

您将无法规避这一点,因为运算符优先级不适用于函数调用参数子句;后者(及其“优先级”)由函数调用表达式的语法定义。

关于swift - 优先级高于闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41722819/

相关文章:

swift - 带有边框和背景问题的 UILabel

ios - 滚动时 UIScrollView 对齐位置

swift - 将 cookie 传递给 WKWebView/SFSafariViewController?

swift - 当前用户 UID 与身份验证 UID 不同吗?

xcode - 类型 'String' 不确认协议(protocol) 'NSCopying' 与 NSDictionary

swift - 键盘不会退出 View

ios - 如何构建具有特定行数的 TableView ?

ios - 我的 TableViewCell 自定义类中的 IbOutlet 从未被初始化

arrays - Swift 4 数组将 nil 映射到字符串

ios - 如何让 UILabel 替换 NavigationBar 大标题?