我正在尝试在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() } }
除了使用此运算符的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
我们意识到这里的问题不是"优先级低于闭包",而是函数调用参数子句(任何后缀表达式之后的一组parantheses)将尝试调用该后缀表达式,就好像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会将一个函数调用参数子句应用于紧接在前面的后缀表达式条款.在您的示例中,bar
构成该后缀表达式,并且仅当您foo --> bar
在parantheses中包装时,组合的包装表达式构成postfix-expression,其上应用以下function-call-argument-clause.
后缀表达式
通过将后缀运算符或其他后缀语法应用于表达式来形成Postfix表达式.从语法上讲,每个主表达式也是一个后缀表达式.
主要表达
主表达式是最基本的表达式.它们可以单独用作表达式,它们可以与其他标记组合以生成前缀表达式,二进制表达式和后缀表达式.
您将无法绕过这一点,因为运算符优先级不适用于function-call-argument-clause; 后者(及其"优先级")由函数调用表达式的语法定义.