将类型模式匹配转换为类型 class

Convert type pattern maching to type class

我有以下代码:

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)
}

如何将其转换为使用类型 class?

编辑:

有人问我数组的类型是什么。情况很复杂。数组声明如下:

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 通常被认为是一种代码味道。但是,如果你做不到或者为了收益而做太多的工作,那么类型类就是不适合这项工作的工具。