2012-11-22 24 views
6

說我有一個功能用可變參數調用帶有命名參數的函數的Scala語法是什麼?

def f(a:Int = 0, b:String = "", c:Float=0.0, foos: Foo*) { ... } 

注意使用默認參數的一些參數。通常情況下,儘量使用默認值,你調用一個函數命名參數,如下所示:

val foo = Foo("Foo!") 
f(foos = foo) 

這句法的作品,因爲我只是調用方法與一個foo。但是,如果我有兩個或更多的

val foo1 = Foo("Foo!") 
val foo2 = Foo("Bar!") 
f(foos = ...) 

它不是那麼明顯什麼應該喂在這裏。 Seq(foo1,foo2)Seq(foo1,foo2):_*不要鍵入檢查。

更重要的是,我怎樣稱呼它foo s?

// All out of foos! 
f(foos = ...) 

對於這種情況,調用帶有空括號(f())的功能不起作用。

謝謝!

+0

你使用的是什麼版本的scala? 2.9.2試圖在REPL中定義f會給我一個「:9:錯誤:帶有參數'*'的參數段不允許有默認參數」 –

+0

我在2.9.2上看到這個爲好。但是,我正在編譯的實際代碼正在運行2.9.1,顯然這是合法的。 – fatuhoku

回答

7

由於斯卡拉2.9侷限性保羅提到的,你仍然可以使用鑽營來劃分不同部分的參數,一個使用具有默認參數的命名參數,另一個使用可變參數(如果需要多個可變參數,則使用多個curried參數部分)。關於可讀性,結果是imho幾乎比只使用命名參數更好:

f(b="something")() 
f(c=3.14)(foo1, foo2) 
+0

這實際上是一個不錯的主意,謝謝! – fatuhoku

+0

我同意,這看起來不錯! –

8

有關默認參數,請參閱我對您問題的評論。對於如何使用命名參數調用一個可變的部分,見下文(斯卡拉2.9.2):

scala> case class Foo(a:Int) 
defined class Foo 

scala> def f(a:Int, foos: Foo*) = foos.length 
f: (a: Int, foos: Foo*)Int 

scala> f(a=2, foos=Foo(2)) 
res0: Int = 1 

// I'm not sure if this is cheating... 
// am I just naming the first of the two variadic arguments? 
scala> f(a=2, foos=Foo(2),Foo(3)) 
res1: Int = 2 

//anyway you can do .... 
scala> f(a=2, foos=Seq(Foo(1), Foo(2)):_*) 
res2: Int = 2 

// with no foos... 
scala> f(a=2, foos=Nil:_*) 
res3: Int = 0 
+0

謝謝,這很清楚。我會接受你的答案,因爲它更接近這個問題,不過就實用性而言,我認爲我會採用bluenote10的方法。 – fatuhoku

+0

@fatu我知道我的答案是[技術上正確的](www.deadprogrammer.com/technically-correct/)...我也認爲bluenote10的方法更好,是一個更有用的正確品牌。你仍然可以不接受我的答案並接受他的答案。 –

+0

哈哈,好吧,如你所願。 – fatuhoku

相關問題