2015-11-14 36 views
0

當你寫List(1,2,3).toSet()而不是List(1,2,3).toSet會發生什麼?第一個表達式返回Boolean。爲什麼?.toSet和.toSet()有什麼區別?

+2

它似乎等同於'.toSet' ['.apply()'](http://www.scala-lang.org/api/current/index.html#[email protected]申請(ELEM:A):布爾) – Bergi

回答

6

寫作List(1,2,3).toSet() REPL運行等同於:

List(1,2,3).toSet(()) 

List(1,2,3).toSet.apply(()) 

List(1,2,3) toSet() 

List(1,2,3).toSet apply() 

也就是說,您呼叫中的()不是空的apply。這是一個Unit。所以toSetList轉換爲Set。編譯器會看到(),但知道在Set上沒有空的apply方法,所以它會假設您必須嘗試在沒有括號的情況下調用Set#apply,並且將()作爲參數傳遞給它。

這很令人困惑,這就是爲什麼這個用法不被使用。

$ scala -deprecation 

scala> List(1,2,3).toSet() 
<console>:11: warning: Adaptation of argument list by inserting() has been deprecated: this is unlikely to be what you want. 
     signature: GenSetLike.apply(elem: A): Boolean 
    given arguments: <none> 
after adaptation: GenSetLike((): Unit) 
     List(1,2,3).toSet() 
         ^

注意這些棄用警告。

2

它與Bergi提到的.set .apply()等效。

但還有更多;怎麼一回事,因爲適用()方法需要elem: A參數,但在這裏我們只要使用toSet(),和編譯器的修改給予任何幫助我們(但可能不應該),並將其變爲

GenSetLike((): Unit) 

滿足簽名,但是不贊成這種方式,檢查here.

編輯:如果您-deprecated你應該看到警告

<console>:11: warning: Adaptation of argument list by inserting() has been deprecated: this is unlikely to be what you want. 
    signature: GenSetLike.apply(elem: A): Boolean 
    given arguments: <none> 
    after adaptation: GenSetLike((): Unit) 
    List(1,2,3).toSet.apply() 
    res1: Boolean = false