简体   繁体   中英

Scala case class arguments instantiation from array

Consider a case class with a possibly large number of members; to illustrate the case assume two arguments, as in

case class C(s1: String, s2: String)

and therefore assume an array with size of at least that many arguments,

val a = Array("a1", "a2")

Then

scala> C(a(0), a(1))
res9: C = c(a1,a2)

However, is there an approach to case class instantiation where there is no need to refer to each element in the array for any (possibly large) number of predefined class members ?

No, you can't. You cannot guarantee your array size is at least the number of members of your case class.

You can use tuples though.

Suppose you have a mentioned case class and a tuple that looks like this:

val t = ("a1", "a2")

Then you can do:

c.tupled(t)

Having gathered bits and pieces from the other answers, a solution that uses Shapeless 2.0.0 is thus as follows,

import shapeless._
import HList._
import syntax.std.traversable._

val a = List("a1", 2)                    // List[Any]
val aa = a.toHList[String::Int::HNil]
val aaa = aa.get.tupled                  // (String, Int)

Then we can instantiate a given case class with

case class C(val s1: String, val i2: Int)
val ins = C.tupled(aaa)

and so

scala> ins.s1
res10: String = a1

scala> ins.i2
res11: Int = 2

The type signature of toHList is known at compile time as much as the case class members types to be instantiate onto.

To convert a Seq to a tuple see this answer: https://stackoverflow.com/a/14727987/2483228

Once you have a tuple serejja's answer will get you to a c .

Note that convention would have us spell c with a capital C .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM