问题
I have the following code:
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)
}
How can I convert it to use type class?
Edit:
I was asked what the type of the array is. It's complicated. The array is declared like that:
val array = obj.asInstanceOf[mutable.WrappedArray[Any]].array
obj is a parameter that the function accepts:
val createBuffer = (obj: Any, dType: DataType) => dType match {
The function is called here:
val byteBuffer: Option[ByteBuffer] = createBuffer(row.get(i), types(i))
row is a Spark DataFrame row.
回答1:
A typeclass would look like this:
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)
}
}
}
Which you can use like:
import syntax.bytes._
val arr: Array[Int] = ???
val byteBuffer = arr.allocateByteBuffer
You may even provide more useful extension methods, like instead of just allocating the ByteBuffer, you can fill it directly.
Note, remember typclasses are type driven, thus are resolved at compile time.
If you do not know the type of your array, then that pattern match is the best you can do.
You may want to see if you can refactor your code so it becomes more strongly types, since Any, in general, is considered a code smell. But, if you can't or it is too much work for the benefits, then typeclasses are simply the wrong tool for the job.
来源:https://stackoverflow.com/questions/61443874/convert-type-pattern-maching-to-type-class