2013-08-20 14 views
6

Ho scritto una classe che accetta un varargs come parametro, e specificare la sua impostazione predefinita in modo che un utente può spesso un'istanza senza specificare un parametro:Perché è impossibile specificare il valore predefinito di un parametro varargs Scala?

class MyClass(values: Int* = 42) { } 

Tuttavia, il compilatore ed il REPL mi danno i seguenti errori :

<console>:7: error: type mismatch; 
found : Int(42) 
required: Int* 
     class MyClass(values: Int* = 42) { } 
           ^
<console>:7: error: a parameter section with a `*'-parameter is not allowed to have default arguments 
     class MyClass(values: Int* = 42) { } 

Come una soluzione, ho provato quanto segue, ma non ha funzionato neanche: (. è molto ambigua ovviamente)

class MyClass(value: Int = 42, otherValues: Int*) { } 

Mi chiedo perché non sia consentito avere il valore predefinito per un parametro varargs. Qual è il ragionamento o la ragione tecnica che giace sotto? (La mia ipotesi è che specificare un varargs vuoto richiederebbe una sintassi o un idioma speciale, ma non sono sicuro se questo è un motivo sufficiente.)

risposta

5

Pensando un po 'di questo, penso che sia solo una questione di non aggiungere troppa complessità, si supponga di avere

def f(a: A, xs: X* = Seq(x0, x1)) = ??? 

Ora il chiamante utilizza in questo modo: f(a).

Come si fa a sapere se il chiamante intendeva passare un elenco a lunghezza zero di o desiderava attivare gli argomenti predefiniti non fornendo uno ? Nell'esempio si presuppone che la seconda alternativa sia l'unico caso che sarà mai e che il compilatore deve fornire il valore di argomento predefinito. Ma uno Seq() vuoto è già un valore perfettamente valido fornito dal chiamante. Immagino che il chiamante possa scrivere f(a, Seq(): _*) ma è ingombrante.

+0

Perché 'def foo (risultato: Int = 0, xs: String *) = ???' non è accettabile allora? È perfettamente fattibile per il compilatore riconoscere 'foo (0," impossible to compile ")' come una costruzione legale. –

+0

@ om-nom-nom, non sono sicuro di seguirti.Sto rispondendo perché potremmo non voler supportare 'def foo (risultato: Int = 0, xs: String * = Seq (" some "," default ")) = ???'. – huynhjl

+0

sì, ma il compilatore mette la stessa restrizione nel mio caso (almeno ci dà lo stesso errore di compilazione), quindi immagino ci possa essere qualche altra ragione che unifica questi due casi –

3

Varargs, non solo in Scala, è un'astrazione su un elenco di argomenti , se non sbaglio è desugared in Seq, una lista degli argomenti. Derivando da questo, quale risultato ti aspetti da values: Int* = 42? E poi, quando chiami questo metodo, come dovrebbero essere passati argomenti in questo metodo?

+2

Ma si potrebbero fare i seguenti valori: Int * = (Matrice (42): Int *) ' – Jatin

5

Da specifica Scala (sezione 4.6.2)

Non è consentito per definire eventuali argomenti di default in una sezione di parametro con un parametro ripetuto

Forse una soluzione aiuterebbe?

class MyClass(values: Int*) { 
    def this() = this(5) 
} 
+1

Non spiega perché sia ​​così, postula tale rifiuto. –

2

Un'altra soluzione è quella di rendere il Seq esplicito:

class MyClass(values: Seq[Int] = Seq(42)) { } 
+0

Sì, questa è la soluzione che ho trovato. – trustin

2

un valore predefinito a varargs solo non ha senso, dal momento che non si riesce a capire come devono essere passati molti argomenti. Questa non è una limitazione di scala, questa è una limitazione logica.

Problemi correlati