爲了補充其他答案,下面是一些例子,說明在使用'_'作爲佔位符參數時,在某些情況下爲什麼會出現「缺少參數類型」。
Scala的類型推斷根據上下文考慮表達式的'expected'類型。如果沒有上下文,則不能推斷參數的類型。在錯誤消息中注意_
的第一個和第二個實例被編譯器生成的標識符x$1
和x$2
所取代。
scala> _ + _
<console>:5: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
_ + _
^
<console>:5: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
_ + _
^
添加類型歸屬到整個表達式提供足夠的上下文來幫助inferencer:
scala> (_ + _) : ((Int, Int) => Int)
res3: (Int, Int) => Int = <function2>
或者,你可以添加一個類型歸屬到每個參數佔位符:
scala> (_: Int) + (_: Int)
res4: (Int, Int) => Int = <function2>
在下面的函數調用中提供了類型參數,上下文是不可信的,並且函數類型被推斷出來。
scala> def bar[A, R](a1: A, a2: A, f: (A, A) => R) = f(a1, a2)
bar: [A,R](a1: A,a2: A,f: (A, A) => R)R
scala> bar[Int, Int](1, 1, _ + _)
res5: Int = 2
但是,如果我們要求編譯器推斷類型的參數,如果失敗:
scala> bar(1, 1, _ + _)
<console>:7: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
bar(1, 1, _ + _)
^
<console>:7: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
bar(1, 1, _ + _)
^
我們能幫助它,但是,通過討好的參數列表。這裏,第一個參數列表(1, 1)
的參數告訴推論,類型參數A
應該是Int
。然後它知道參數f
的類型必須是(Int, Int) => ?)
,並且返回類型R
被推斷爲Int
,即整數加法的結果。您會在標準庫中看到Traversable.flatMap
中使用的相同方法。
scala> def foo[A, R](a1: A, a2: A)(f: (A, A) => R) = f(a1, a2)
foo: [A,R](a1: A,a2: A)(f: (A, A) => R)R
scala> foo[Int, Int](1, 1) { _ + _ }
res1: Int = 2
scala> foo(1, 1) { _ + _ }
res0: Int = 2
@Scoobie爲了強化這一點,下劃線用於Scala中許多_different_目的。正如David解釋的那樣,在你的例子中每個用途實際上都有不同的含義。還有其他一些含義 - 在Scala中強調,是運算符超載導致問題的一個很好的例子。雖然起初我有問題,但我可以誠實地說,我從來沒有想過通過某種方式來改進它。 – 2010-03-01 01:38:41