【发布时间】:2012-11-01 08:04:57
【问题描述】:
是否可以在 Scala 中专门化泛型函数(或类)?例如,我想编写一个将数据写入 ByteBuffer 的通用函数:
def writeData[T](buffer: ByteBuffer, data: T) = buffer.put(data)
但由于 put 方法只需要一个字节并将其放入缓冲区,因此我需要将其专门用于 Ints 和 Longs,如下所示:
def writeData[Int](buffer: ByteBuffer, data: Int) = buffer.putInt(data)
def writeData[Long](buffer: ByteBuffer, data: Long) = buffer.putLong(data)
它不会编译。当然,我可以分别编写 3 个不同的函数 writeByte、writeInt 和 writeLong,但假设还有另一个函数用于数组:
def writeArray[T](buffer: ByteBuffer, array: Array[T]) {
for (elem <- array) writeData(buffer, elem)
}
如果没有专门的 writeData 函数,这将无法工作:我将不得不部署另一组函数 writeByteArray、writeIntArray、writeLongArray。每当我需要使用依赖于类型的写入函数时,必须以这种方式处理这种情况并不酷。我做了一些研究,一种可能的解决方法是测试参数的类型:
def writeArray[T](buffer: ByteBuffer, array: Array[T]) {
if (array.isInstanceOf[Array[Byte]])
for (elem <- array) writeByte(buffer, elem)
else if (array.isInstanceOf[Array[Int]])
for (elem <- array) writeInt(buffer, elem)
...
}
这可能有效,但效率较低,因为类型检查是在运行时完成的,与专用函数版本不同。
所以我的问题是,在 Scala 或 Java 中解决此类问题的最理想和首选的方法是什么?提前感谢您的帮助!
【问题讨论】:
-
等待类型类答案在 3... 2... 1..
-
添加了
specialized标签,因为事实证明这意味着 Scala 中的特定内容,而这正是您所需要的。 -
@RexKerr:我看不出
@specialized在这里有什么相关性——这无助于选择需要putInt、putLong等中的哪一个。 -
@TravisBrown - 不,但它会让你不会因为你这样做而不是每次都从头开始实施而感到抱歉。向缓冲区添加字节不是您通常想要调用装箱的事情。
标签: java scala generics specialized-annotation