2017-07-25 96 views
3

Scala的定義方法的時候,我發現這個聲明參數類型時Scala lambda函數未解析?

def method1: Int => Int = (j: Int) => j // works 
def method2: Int => Int = j => j // works 
def method3: Int => Int = j: Int => j // error 
def method4: Int => Int = {j: Int => j} // works 

任何人都可以解釋爲什麼方法3不起作用?它有什麼含糊之處嗎?

回答

2

一個可能的解釋確實是這種限制避免了歧義:x: A => B可以理解爲一個匿名函數,它A類型的參數x並返回對象B。或者它可以被理解爲「鑄造」x變量爲A => B。這些都是有效的計劃是非常罕見的,但並非不可能。試想一下:

class Foo(val n: Int) 
val Foo = new Foo(0) 
val j: Int => Foo = new Foo(_) 

def method1: Int => Foo = (j: Int) => Foo 
def method2: Int => Foo = j: Int => Foo 

println(method1(1).n) 
println(method2(1).n) 

這實際上編譯並打印:

0 
1 
+0

這看起來像我正在尋找的正確答案,謝謝! –

0

所有這些變體都由Anonymous Functions section of the specification覆蓋。相關部分是

在一個非類型化的形式參數的情況下,(x) => e 可以縮寫爲 x => e。如果具有單一類型參數的匿名函數(x : T) => e 作爲塊的結果表達式出現,則可將其縮寫爲 x: T => e

method3中,該函數不是塊的結果表達式;在是。

編輯:哎呀,大概你的意思是爲什麼限制在那裏。現在我將留下這個答案,說明限制是什麼,如果有人給出更好的答案,將其刪除。

+0

你介意解釋什麼手段「塊的結果表達式」?它是否意味着「{}」? –

+0

@RossKeth是的。Scala中的一種表達式是一個塊表達式:0,1個或多個表達式由'{''}包圍。塊的結果表達式是它的最後一個表達式 –