2011-07-10 26 views
45

不是toList將某個東西轉換成List的方法嗎?Scala方法調用中括號的規則是什麼?

如果是,那麼爲什麼我不能使用括號?我必須在這裏錯過更重要的東西。

這裏是例如:

val l = Array(1,2,3).toList // works fine 

val l = Array(1,2,3).toList() // gives the error below 

沒有足夠的參數爲方法適用:(N:智力)詮釋在性狀 LinearSeqOptimized。未指定的值參數n。

+0

在這裏找到一個類似的問題,可能有所幫助:[困惑關於Scala方法調用約定,特別是Seq上的求和函數](http://stackoverflow.com/questions/5545027/confused-about-scala-method-calling-約定,特別是總和功能) – jwinn

回答

55

如果一個方法被定義爲

def toList = { /* something */ } 

那麼它必須被稱爲

object.toList 

,沒有額外的括號。我們說這個方法有零參數列表

我們也可以定義一個參數列表,但放什麼也沒有:

def toList() = { /* something */ } 

現在,我們可以調用之一

object.toList() 
object.toList 

在Scala允許在方法調用中省略括號的快捷方式。就JVM而言,第一個定義(「零參數列表」)和第二個(「一個空參數列表」)之間沒有區別。但斯卡拉保持區別。這是否是一個好主意與否是有爭議的,但是當你意識到,我們也可以

def toList()() = { /* something */ } 

這被稱爲兩個空的參數列表,然後調用任何

的動機可能是更清晰
object.toList()() 
object.toList() 
object.toList 

現在,如果我們將它轉​​換成一個功能,我們可以鍵入它作爲

() =>() => T /* T is the return value of the something */ 

而第二個定義是

() => T 

這顯然是不同的概念,即使實際上你用同樣的方式(放什麼,遲早得到了T)。

無論如何,toList不需要任何參數,Scala標準是除非方法改變對象本身(而不是僅僅返回一些東西),所以它的def toList之後沒有任何parens。因此,您只能將其稱爲object.toList。因爲foo(x)

+1

你的解釋很好。我很難想象toList()()的用途,但我現在將信任scala ... – TraderJoeChicago

+7

您忘了提及額外的括號給出了一個錯誤,因爲它被認爲是'apply'方法產生'List'。 –

+0

@丹尼爾 - 好點。但是,如果沒有適用的話,人們總是會回頭忽略對方,所以這並不能完全解決問題。我會讓人們閱讀你對此解釋的評論:) –

21

你的第二個行實際上是解釋爲

val l = Array(1,2,3).toList.apply() 

foo.apply(x) 「神奇」 的語法。

這就是爲什麼編譯器抱怨「沒有足夠的參數」,因爲list上的apply方法需要一個參數。

因此,你可以寫例如: -

scala> val i = Array(1, 2, 3).toList(1) 
i: Int = 2 
+0

也許這就是爲什麼如果方法沒有參數,最好不要聲明它,然後你可以像上面那樣使用「鏈接」。 – TraderJoeChicago

+0

但同時很難判斷(1)是方法的參數還是應用於方法結果。 : - | – TraderJoeChicago

+0

這實際上是正確答案,不確定爲什麼OP將最高答案標記爲正確答案。 –

3

讓我從斯卡拉回答編碼風格的角度。

的Scala style guide說...

省略空括號,僅當所討論的方法沒有副作用(純功能性)使用。換句話說,在調用queue.size時省略括號是可以接受的,但在調用println()時不會。

宗教上遵守這個約定會顯着提高代碼的可讀性,並且使得一目瞭然地理解任何給定方法的最基本操作變得更容易。爲了保存兩個字符,抵制省略括號的衝動!

相關問題