1

I have one issue for a function that I wrote about the conversion of one Array[Byte] to a Array[T]. The function in question :

def getPoints[T](bytes : Array[Byte]) : Array[T] = {
      val byteBuffer = ByteBuffer.wrap(bytes)
      byteBuffer.order(ByteOrder.LITTLE_ENDIAN)
      val data = Array.ofDim[T](bytes.length / biosRecord.byteEncoding)
      if(biosRecord.byteEncoding == 2) {
        byteBuffer.asShortBuffer.get(data)
        data
      } else if(biosRecord.byteEncoding == 4) {
        byteBuffer.asIntBuffer().get(data)
        data
      } else null
    }

biosRecord is a case class with a int field (byteEncoding).

I know there is two problems in this code :

  1. To return a generic array, I need to use Manifest.
  2. In the first if branch, the inferred type is Array[Short] and in the second one is Array[Int]. This is why I tried to use a generic type T but it not works.

What I get at the compilation time :

[error]   (x$1: Array[Short])java.nio.ShortBuffer <and>
[error]   (x$1: Int)Short
[error]  cannot be applied to (Array[T])
[error]         byteBuffer.asShortBuffer.get(data)

[error]   (x$1: Array[Int])java.nio.IntBuffer <and>
[error]   (x$1: Int)Int
[error]  cannot be applied to (Array[T])
[error]         byteBuffer.asIntBuffer().get(data)

What do I need to do in order to make this generic function compiles ?

1
  • I see two problems, byteBuffer.asShortBuffer.get(data) get here takes an int or an Array[Short] but your array is generic, second ofDim needs an implicit ClassTag for your T. Commented Apr 28, 2016 at 10:49

1 Answer 1

4

The signature def getPoints[T](bytes : Array[Byte]) : Array[T] means that the caller can decide what T is. For instance, by calling:

val myResult = getPoints[String](myBytes)

I'm making getPoints return an Array[String], regardless of the value of myBytes.

In other words - what you're trying to do is not possible. You cannot parameterize a method's type based on "decisions" inside the method body.

Perhaps what you want to do here is use the best common type that is a superclass of all possible return types. In this case:

def getPoints(bytes : Array[Byte]) : Array[AnyVal] = {
    // can return Array[Int], Array[Short]...
}

This way, the caller can't force the type, and doesn't know the type, all they know is that it's one of the subclasses of AnyVal.

Sign up to request clarification or add additional context in comments.

1 Comment

I understood and to fix this error, I use an ADT. Thank you for your explanation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.