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

问题描述 投票:2回答:1

我有以下代码:

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行。

scala apache-spark functional-programming pattern-matching typeclass
1个回答
0
投票

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视为代码气味,但是如果不能,或者它对于好处,那么类型类就是工作的错误工具。
© www.soinside.com 2019 - 2024. All rights reserved.