2012-11-22 18 views
6

Ben bir işlevDeğişken argümanlarla, ancak adlandırılmış argümanlarla bir işlevi çağırmak için Scala sözdizimi nedir?

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

Bildirimi bazı parametreler için varsayılan argümanlar kullanılması olduğunu düşünelim. Tipik olarak, varsayılan değerler faydalanmak için, bunu böyle adlandırılmış parametreleri ile bir fonksiyonu çağırmak: Sadece bir foo ile yöntemini hatırlatıyorum çünkü

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

Bu sözdizimi çalışır. Ben iki veya daha fazla

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

varsa Ancak, burada beslenmek gerektiği çok açık değil. Seq(foo1,foo2) ve Seq(foo1,foo2):_* kontrol yazmayın.

Dahası, nasıl nofoo s ile arayabilirim? çalışmıyor boş parantez (f()) ile işlevini çağırarak bu durumda İçin

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

.

Teşekkürler!

+0

Hangi scala versiyonunu kullanıyorsunuz? 2.9.2 REPL'de f'yi tanımlamaya teşebbüs etmek bana ": 9: hatası:' * 'parametresine sahip bir parametre bölümü - parametrenin varsayılan argümanlara sahip olmasına izin verilmiyor " –

+0

Bunu 2.9.2 olarak görüyorum iyi. Ancak, derlediğim asıl kod, yasal olduğu anlaşılan 2.9.1 sürümünü çalıştırıyor. – fatuhoku

cevap

7

, yine farklı bölümlerde parametreleri bölmek için currying kullanabilirsiniz, varsayılan argümanlarla adlandırılmış parametreleri kullanan ve bir varargs (veya birden fazla vararg parametresi istiyorsanız birden çok curried argüman bölümü). Okunabilirlik açısından sonuç sadece isimlendirilmiş argümanları kullanmaktan daha iyidir:

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

Bu aslında oldukça iyi bir fikir, teşekkürler! – fatuhoku

+0

Katılıyorum, bu iyi görünüyor! –

8

Varsayılan parametreler için, sorunuza yaptığım yorumu görün. adlandırılmış argümanla variadic kısmını çağırmak nasıl, aşağıda (scala 2.9.2) için bkz:

Paolo bahsettiği Scala 2.9 sınırlamalar göz önüne alındığında
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

Teşekkürler, bu oldukça açık hale getirir. Ben senin cevabını kabul edeceğim çünkü bu soruya daha çok benziyor, ancak pratiklik açısından bluenote10'un yaklaşımını benimsemeyi düşünüyorum. – fatuhoku

+0

@fatu Cevabın [teknik olarak doğru] olduğunu biliyorum (www.deadprogrammer.com/technically-correct /) ... Ayrıca bluenote10'un yaklaşımının daha iyi ve daha kullanışlı bir marka olduğunu düşünüyorum. Hala benimkini kabul edemez ve cevabını kabul edebilirsin. –

+0

Haha, tamam, dilediğiniz gibi. – fatuhoku