我正在尝试使用高于闭包的优先级组在Swift中定义自定义运算符。特别是,我希望能够写下:
foo --> bar {
//...
}
-->
运算符返回一个函数,该函数采用() -> Void
类型的闭包作为唯一参数。
然而,我只能得到
(foo --> bar) {
//...
}
上班。是否有一个运算符优先级可以使这个工作没有括号?
这是
的优先组precedencegroup LongArrowPrecedence {
associativity: left
higherThan: AssignmentPrecedence
}
infix operator --> : LongArrowPrecedence
谢谢!
答案 0 :(得分:5)
我们首先建立了一个完整且可验证的例子:
precedencegroup LongArrowPrecedence {
associativity: left
higherThan: AssignmentPrecedence
}
infix operator --> : LongArrowPrecedence
func -->(lhs: Int, rhs: Int) -> (() -> ()) -> () {
return { print(lhs+rhs, terminator: ""); $0() }
}
除了使用此运算符的paranthesis-embraced有效调用的示例之外,紧接着调用-->
返回的闭包。
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(任何postfix-expression之后的一组parantheses)将尝试< em>调用到该postfix-expression,就好像postfix-expression是一个方法/函数/闭包。如果postfix-expression不可调用,或者如果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将应用一个函数调用参数子句到紧接在子句之前的postfix-expression。在您的示例中,bar
构成该后缀表达式,并且仅当您将foo --> bar
包装在parantheses中时,组合的包装表达式才构成postfix-expression,其上应用了以下function-call-argument-clause。
后缀表达式
Postfix表达式是通过应用后缀运算符或其他形式来形成的 postfix语法到表达式。 从句法上讲,每个主要的 表达式也是一个后缀表达式。
主要表达
主表达式是最基本的表达方式。他们可以 用作表达式,可以与其他表达式结合使用 令牌用于创建前缀表达式,二进制表达式和后缀 表达式。
您将无法绕过这一点,因为运算符优先级不适用于function-call-argument-clause;后者(及其“优先级”)由函数调用表达式的语法定义。