我有以下代码:
val byteBuffer = array(0) match {
case _: Int =>
ByteBuffer.allocate(4 * array.length)
case _: Long =>
ByteBuffer.allocate(8 * array.length)
case _: Float =>
ByteBuffer.allocate(4 * array.length)
case _: Double =>
ByteBuffer.allocate(8 * array.length)
case _: Boolean =>
ByteBuffer.allocate(1 * array.length)
}
如何将其转换为使用类型类?
编辑:
我被问到数组的类型是什么。情况很复杂。数组声明如下:
val array = obj.asInstanceOf[mutable.WrappedArray[Any]].array
obj是函数接受的参数:
val createBuffer = (obj: Any, dType: DataType) => dType match {
此函数在这里调用:
val byteBuffer: Option[ByteBuffer] = createBuffer(row.get(i), types(i))
行是Spark DataFrame行。
A typeclass看起来像这样:
trait ByteSize[T] {
def tSize: Int
}
object ByteSize {
implicit final val IntByteSize: ByteSize[Int] =
new ByteSize[Int] {
override final val tSize: Int = 4
}
implicit final val LongByteSize: ByteSize[Long] =
new ByteSize[Long] {
override final val tSize: Int = 8
}
// Other instances.
}
object syntax {
object bytes {
implicit class ArrayOps[T](private val arr: Array[T]) extends AnyVal {
final def allocateByteBuffer(implicit ev: ByteBuffer[T]): ByteBuffer =
ByteBuffer.allocate(ev.tSize * array.length)
}
}
}
您可以这样使用:
import syntax.bytes._
val arr: Array[Int] = ???
val byteBuffer = arr.allocateByteBuffer
您甚至可以提供更有用的扩展方法,例如,您可以直接填充它,而不仅仅是分配ByteBuffer。
注意,请记住typclasses
是类型驱动的,因此在编译时被解析。如果您不知道数组的类型,那么该模式匹配就是您可以做的背心。您可能想看看是否可以重构代码,使其成为更强大的类型,因为通常将Any视为代码气味,但是如果不能,或者它对于好处,那么类型类就是工作的错误工具。