scala - 将类型模式加工转换为类型类
问题描述
我有以下代码:
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 行。
解决方案
一个类型类看起来像这样:
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,你可以直接填充它。
注意,记住类型类是类型驱动的,因此在编译时被解析。如果您不知道数组的类型,那么该模式匹配是您能做的最好的事情。
你可能想看看你是否可以重构你的代码,让它变成更强的类型,因为Any,一般来说,被认为是代码异味。但是,如果你做不到,或者工作量太大,那么类型类就是不适合这项工作的工具。
推荐阅读
- c# - ImageButton 不在网格列中居中
- javascript - angular和nodejs文件之间的连接
- java - 如何分组和连接值?
- java - “app-release.apk”如何更改这个默认生成的apk名称,允许之后安装?
- c# - 在 .net core / webpack web 应用程序中注入 css 样式的最佳实践
- excel - 跟踪正在使用数据库更新的 Excel 工作簿的更改。(非共享工作簿)
- jquery - $.ajax 不工作?我如何在 jQuery onclick 函数中调用 ajax?
- django - 如何从 djnago 中的相关表中检索数据
- python - 我一直在 Swift 中使用一个具有出色返回闭包的函数
- python - Tensorflow:将未知大小的张量拆分为给定大小的块