Supponiamo che dichiaro una funzione come segue:Qual è il tipo di elenco di argomenti a lunghezza variabile in Scala?
def test(args: String*) = args mkString
Qual è il tipo di args
?
Supponiamo che dichiaro una funzione come segue:Qual è il tipo di elenco di argomenti a lunghezza variabile in Scala?
def test(args: String*) = args mkString
Qual è il tipo di args
?
Questo è chiamato un numero variabile di argomenti o in brevi vararg. Il suo tipo statico è Seq[T]
dove T
rappresenta T*
. Poiché Seq[T]
è un'interfaccia, non può essere utilizzata come implementazione, che in questo caso è scala.collection.mutable.WrappedArray[T]
. Per scoprire queste cose può essere utile per utilizzare il REPL:
// static type
scala> def test(args: String*) = args
test: (args: String*)Seq[String]
// runtime type
scala> def test(args: String*) = args.getClass.getName
test: (args: String*)String
scala> test("")
res2: String = scala.collection.mutable.WrappedArray$ofRef
varargs sono spesso usato in combinazione con il simbolo _*
, che è un suggerimento per il compilatore di passare gli elementi di una Seq[T]
a una funzione, invece della sequenza stessa:
scala> def test[T](seq: T*) = seq
test: [T](seq: T*)Seq[T]
// result contains the sequence
scala> test(Seq(1,2,3))
res3: Seq[Seq[Int]] = WrappedArray(List(1, 2, 3))
// result contains elements of the sequence
scala> test(Seq(1,2,3): _*)
res4: Seq[Int] = List(1, 2, 3)
Sì, questo ha e l'effetto interessante che non è possibile passare immediatamente il var-len args, 'def f1 (args: Int *) = args.length; def f2 (args: Int *) = f1 (args) '. Darà 'trovato Seq [Int] mentre Int è richiesto errore di mismatch' nella definizione f2. Per aggirare, devi 'def f2 = f1 (args: _ *)'. Quindi, il compilatore pensa che l'argomento sia un singolo valore e una sequenza allo stesso tempo, in fase di compilazione :) – Val