[英]Scala syntax: why is anonymous function parameter type parsed differently using parenthesis versus curly braces?
鑒於Scala 2.12.6:
val list = List(1)
val x = 2
這有效:
list.map ( y => x + y )
返回List[Int] = List(3)
這有效:
list.map ( (y: Int) => x + y )
返回相同的值。
與此相同:
list.map { (y: Int) => x + y }
與此相同:
list.map { y: Int => x + y }
但這失敗了:
list.map ( y: Int => x + y )
產生錯誤:
error: not found: type +
list.map ( y: Int => x + y )
^
為什么Scala認為+
表示一種類型,在括號和花括號之間的區別在哪里記錄和解釋了?
關於匿名函數的第6.23節說:
在單個無類型形式參數的情況下,(x)=> e可以縮寫為x => e。 如果帶有單個類型參數的匿名函數(x:T)=> e出現在塊的結果表達式中,則可以將其縮寫為x:T => e。
因此,在塊{ ... }
,函數文字(y: Int) => x + y
可以縮寫為y: Int => x + y
。
如果沒有該塊,則將整個Int => x + y
-part視為類型歸因,因此錯誤消息實際上是有意義的。 例如,這是一個有問題的表達式在其中生效的上下文:
type y = Unit
type x = Unit
type +[A, B] = Int
val y = (i: Int) => 42 + i
val list = List(1)
println(
list.map ( y: Int => x + y )
) // happily prints `List(43)`.
這是因為在兩個單獨的范圍(一個值,一個類型別名)中有兩個y
,因此(y: Int => x + y)
變為(y: Int => +[x, y])
,然后(y: Int => Int)
,這只是一個類型說明,用於強制值y
確實具有Int => Int
函數類型(確實如此,因此所有內容均可編譯並運行)。 這是另一個類似的例子。
我的建議:堅持使用稍微冗長的(foo: Foo) => { ... }
表示法,這對於嘗試閱讀和修改代碼的每個人來說,都會減少驚喜。 否則存在一些風險
=>
的匿名lambda與功能類型沖突=>
+
與二進制中綴類型構造函數相沖突+[_,_]
x
, y
與未定義的類型x
, y
相撞。 相同的語法可以表示類型和表達式的事實可能有點像一把雙刃劍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.