Reputation: 2441
I'm trying to find a way to write the following code elegantly with scala :
case class Foo(type: String, value: Array[Byte])
The value member holds an array that can be of different type. For example if type = "Double"
it should store an Array[Double]
and for type = "Float"
it should store an Array[Float]
and so on. Currently, I convert my Array[T] into Array[Byte] but it's not very convenient. Is it possible to have a parameter for my case class and just set the value with the concrete type
value: Array[Type] = some: Array[ConcreteType]
Best
Upvotes: 1
Views: 63
Reputation: 127791
It is impossible to express exactly what you want in Scala type system, because it would require dependent types. You can, however, do something very similar:
case class Foo[T: ClassTag](innerArray: Array[T]) {
val classTag = implicitly[ClassTag[T]]
}
That way you will be able to do something like this:
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class Foo[T: ClassTag](innerArray: Array[T]) {
val classTag = implicitly[ClassTag[T]]
}
// Exiting paste mode, now interpreting.
defined class Foo
scala> Foo(Array[Int](1, 2, 3))
res0: Foo[Int] = Foo([I@17160134)
scala> res0.classTag.runtimeClass.getSimpleName
res1: String = int
See how Scala automatically provides a ClassTag
for you. Using that ClassTag
you will be able to recover class name, and, moreover, Scala will force that ClassTag
corresponds exactly to T
and not to some other type.
Upvotes: 2
Reputation: 41
You can use type parameters in case class definition:
case class Foo[T](typeName: String, innerArray: Array[T])
val intArray: Array[Int] = Array(1,2,3)
val foo = Foo("foo", intArray)
val stringArray: Array[String] = Array("a", "b", "c")
val bar = Foo("bar", stringArray)
Upvotes: 0