Reputation: 2937
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 :
Manifest
. 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 ?
Upvotes: 1
Views: 7980
Reputation: 37832
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
.
Upvotes: 4