2011-08-12 47 views
14

我猜測,出於兼容性原因,可變參數Any*的類型是數組[任何] - 請糾正這個,如果我錯了。然而,這並不能說明以下錯誤:Scala:構造函數採取Seq或可變參數

class Api(api_url: String, params: Seq[(String, String)]) { 
    def this(api_url: String, params: (String, String)*) 
    = this(api_url, params.seq) 
} 

此代碼不能編譯,而是給出了警告:

double definition: constructor Api:(api_url: String, params: (String, String)*)Api and constructor Api:(api_url: String, params: Seq[(String, String)])Api at line 13 have same type after erasure: (api_url: java.lang.String, params: Seq)Api

那麼,如何定義一個構造採取任何可變參數,或者序列?

回答

24

的方法了結可變參數也總是採取序列,所以沒有必要定義一個輔助構造函數或重載方法。

鑑於

class Api(api_url: String, params: (String, String)*) 

你可以這樣調用它存在params參數此

new Api("url", ("a", "b"), ("c", "d")) 

val seq = Seq(("a", "b"), ("c", "d")) 
new Api("url", seq:_*) 

而且,在你的問題,你調用方法序列。這可能不符合你的意圖。 seq用於確保對結果集合的操作按順序執行而不是並行執行。該方法是在Scala 2.9.0版中的平行集合中引入的。

你可能想要使用的是seq,它返回它被用於轉換爲Seq(或其本身,如果它已經是Seq)的集合。但是,可變參數參數已經被輸入爲Seq,無論如何這是無用的。

+0

謝謝,這真的很有幫助。 :) – wen

+3

我可以指出類型註釋':_ *'是真正使構造函數調用使用順序參數兼容可變參數構造函數。更多細節:http://stackoverflow.com/questions/6051302/what-does-colon-underscore-star-do-in-scala –

9

否:實際上,Any*實際上幾乎與Seq[Any]相同,而不是Array[Any]

要在兩者間歧義,您可以使用該技術來添加一個虛擬的隱含參數,使不同的簽名:

class Api(api_url: String, params: Seq[(String, String)]) { 
    def this(api_url: String, params: (String, String)*)(implicit d: DummyImplicit) = 
    this(api_url, params) 
} 
+0

......不是這個......真的很噁心嗎? – wen

+5

那麼,隨意提供一個不太「噁心」的解決方案! –

+0

當我想出來的時候,我會的。現在,我只需要修改'varargs'構造函數。 ^^ – wen

1

我想你想讓方法調用更漂亮,所以明確的調用_*不是一個選項。在這種情況下,您可以通過方法重載來解決問題。

class Api(api_url: String, params: Seq[(String, String)]) { 
    def this(api_url: String, param : (String, String), params: (String, String)*) 
    = this(api_url, param +: params) 
    def this(api_url: String) 
    = this(api_url, Seq()) 
}