jrabary
jrabary

Reputation: 2441

how to write a class that has array of anything as member

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

Answers (2)

Vladimir Matveev
Vladimir Matveev

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

dpiatkowski
dpiatkowski

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

Related Questions