Załóżmy, że oświadczam funkcję w następujący sposób:Jaki jest typ listy argumentów o zmiennej długości w Scali?
def test(args: String*) = args mkString
Jaki jest rodzaj args
?
Załóżmy, że oświadczam funkcję w następujący sposób:Jaki jest typ listy argumentów o zmiennej długości w Scali?
def test(args: String*) = args mkString
Jaki jest rodzaj args
?
Nazywa się to zmienną liczbą argumentów lub krótkimi varargs. Jego statyczny typ to Seq[T]
, gdzie T
reprezentuje T*
. Ponieważ Seq[T]
jest interfejsem, nie może być używany jako implementacja, która w tym przypadku jest scala.collection.mutable.WrappedArray[T]
. Aby dowiedzieć się takich rzeczy może być przydatna do korzystania z 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 są często używane w połączeniu z _*
symbolu, który stanowi wskazówkę do kompilatora przekazać elementy Seq[T]
do funkcji zamiast samej sekwencji:
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)
Tak, to ma i interesujący efekt, że nie można natychmiast przekazać argumentów var-len, 'def f1 (args: Int *) = args.length; def f2 (args: Int *) = f1 (args) '. Da to 'found Seq [Int], natomiast Int jest wymaganym błędem niedopasowania' w definicji f2. Aby ominąć, musisz 'def f2 = f1 (args: _ *)'. Tak więc, kompilator uważa, że argument jest pojedynczą wartością i sekwencją w tym samym czasie, podczas kompilacji :) – Val