2012-11-22 19 views
6

Say Mam funkcjiCo to jest składnia Scala wywołująca funkcję z argumentami variadic, ale z nazwanymi argumentami?

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

Zauważ użycie domyślnych argumentów dla niektórych parametrów. Zazwyczaj, aby skorzystać z wartości domyślnych, należy wywołać funkcję z nazwanych parametrów tak:

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

Ta składnia działa, ponieważ Ja tylko wywołanie metody z jednej foo. Jeśli jednak mam dwa lub więcej niż jeden, to nie jest to tak oczywiste, co powinno zostać tutaj podane. Powrót na górę Seq(foo1,foo2) i Seq(foo1,foo2):_* nie sprawdzaj typu.

Co więcej, jak można to nazwać z numerami nofoo?

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

W tym przypadku wywołanie funkcji z pustych nawiasów (f()) nie działa.

Dzięki!

+0

jakiej wersji scali używasz? Z 2.9.2 próby zdefiniowania f w REPL daje mi ": błąd 9: sekcja parametru z parametrem" * "nie może mieć domyślne argumenty" –

+0

Widzę to na 2.9.2 jako dobrze. Jednak rzeczywisty kod, który kompiluję, działa 2.9.1, gdzie najwyraźniej jest to zgodne z prawem. – fatuhoku

Odpowiedz

7

Biorąc pod uwagę, że ograniczenia Scala 2.9 Paolo wymienione, można nadal korzystać currying podzielić parametry w różnych sekcjach, taki, który używa nazwanych parametrów z domyślnymi argumentami, a drugi dla varargs (lub wielu przekopiowanych sekcji argumentów, jeśli chcesz mieć więcej niż jeden parametr vararg). Jeśli chodzi o czytelność, wynik jest prawie lepszy niż tylko z użyciem nazwanych argumentów:

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

To całkiem niezły pomysł, dzięki! – fatuhoku

+0

Zgadzam się, że wygląda dobrze! –

8

Domyślne parametry znajdują się w komentarzu do pytania. Aby dowiedzieć się jak nazywają zmiennej liczbie argumentów część o nazwie argumentu, patrz niżej (Scala 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

Dziękuję, to wyjaśnia. Przyjmuję twoją odpowiedź, ponieważ jest ona ściślej związana z pytaniem, chociaż pod względem praktycznym, myślę, że przyjmuję podejście bluenote10. – fatuhoku

+0

@fatu Wiem, że moja odpowiedź jest [technicznie poprawna] (www.deadprogrammer.com/technically-correct /) ... Sądzę też, że podejście bluenote10 jest lepsze i bardziej przydatne. Nadal możesz nie przyjąć mojej i zaakceptować jego odpowiedź. –

+0

Haha, dobra, jak chcesz. – fatuhoku