眾所周知,您可以將運算子直接傳遞給如下函式:
func foo(_ x: (Int, Int) -> Int) {
}
foo( )
但是,當我嘗試在賦值背景關系中執行此操作時,它不起作用:
let f: (Int, Int) -> Int =
它給出了兩個錯誤:
'=' 后的預期初始值
一元運算子不能與其運算元分離
我發現我必須這樣做:
let f: (Int, Int) -> Int = ( )
Swift 究竟是如何決議每一種情況的,允許我在一種情況下省略括號,但在另一種情況下不能省略?
請注意,我不是在詢問 Swift 以這種方式設計的背后的基本原理。我只是詢問產生這種行為的語法產生規則。
在 Swift.org 上,我已經能夠找到這個生產規則,它說運算子是函式呼叫引數:
function-call-argument → operator | identifier ':' operator
但是,我無法找到( ). 我從“帶括號的運算式”開始,它是圍繞“運算式”的一對括號。但“運算子”顯然不是一種“運算式”。
uj5u.com熱心網友回復:
我找到了Swift AST Explorer,它允許我檢查 Swift 代碼的 AST。從它的GitHib 頁面來看,它似乎使用了與 Swift 編譯器用來決議 Swift 代碼(lib/Syntax)相同的庫。
使用 Swift AST Explorer,( )部分let x: (Int, Int) -> Int = ( )決議為:
TupleExpr
(
TupleExprElementList
TupleExprElement
IdentifierExpr
)
顯然,( )這是一個 1 元組!并且 被歸類為“識別符號運算式”。這似乎也解釋了為什么元組元素中的運算子不需要括號:
let f: ((Int, Int) -> Int, (Bool) -> Bool, (Int) -> Int) = ( , !, -)
經過一番搜索,我找到了 ExprNodes.py,它似乎是生成 lib/Syntax 中某些 API 的檔案之一。在那里,我看到它SpacedBinaryOperatorToken是 的孩子IdentifierExpr,所以這可能 是被決議的。
Node('IdentifierExpr', kind='Expr',
children=[
Child('Identifier', kind='Token',
token_choices=[
'IdentifierToken',
'SelfToken',
'CapitalSelfToken',
'DollarIdentifierToken',
'SpacedBinaryOperatorToken',
]),
Child('DeclNameArguments', kind='DeclNameArguments',
is_optional=True),
]),
有趣的是,諸如!和 之-類的一元運算子也被決議為“二元運算子”。
uj5u.com熱心網友回復:
" " 是一個中綴運算子,因此我猜它必須在某些定義的型別(例如 Int 和 Int)之間,并且您不能僅僅宣告它獨立。您可以定義自己的中綴運算子,讓我們用以下代碼說:
infix operator ~
func ~(lhs: Double, rhs: Double) -> Double {
return lhs * lhs rhs * rhs
}
let val1: Double = 2
let val2: Double = 3
let squareSum = val1 ~ val2
print(squareSum)
所以我想你的答案的關鍵是“ ”不僅僅是一些常規函式,而是一個中綴運算子并用括號 (x) 定義它有助于編譯器理解它不介于某些東西之間。希望這個答案可以幫助您提供一些指南,如果您愿意,可以在哪里尋找進一步的解釋。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/354977.html
