Вы можете использовать класс типов, но вы потеряете возможность иметь значение типа, потому что этот шаблон требует использования неявного параметра:
import java.nio.{ByteBuffer, ByteOrder}
trait Bufferable[A] {
def size: Int
def put(a: A, buffer: ByteBuffer): Unit
}
implicit val intBufferable: Bufferable[Int] =
new Bufferable[Int] {
override val size = java.lang.Integer.SIZE / 8
def put(n: Int, buffer: ByteBuffer): Unit = buffer.putInt(n)
}
implicit val longBufferable: Bufferable[Long] =
new Bufferable[Long] {
override val size = java.lang.Long.SIZE / 8
def put(n: Long, buffer: ByteBuffer): Unit = buffer.putLong(n)
}
final case class RichSeq[A](seq: Seq[A])(implicit buf: Bufferable[A]) {
def toByteArray: Array[Byte] = {
val buffer = ByteBuffer.allocate(buf.size * seq.length)
buffer.order(ByteOrder.LITTLE_ENDIAN)
seq.foreach(buf.put(_, buffer))
buffer.array()
}
}
RichSeq(Vector(1, 2, 3)).toByteArray.size // evaluates to 12
RichSeq(Vector(1L, 2L, 3L)).toByteArray.size // evaluates to 24
Вы можете играть с этим кодом здесь, в Scast ie.
Если вы можете, вы, возможно, захотите рассмотреть возможность наличия простого помощника для этого, чтобы вы могли избежать ненужных выделений:
object SeqUtils {
def toByteArray[A](seq: Seq[A])(implicit buf: Bufferable[A]): Array[Byte] = {
val buffer = ByteBuffer.allocate(buf.size * seq.length)
buffer.order(ByteOrder.LITTLE_ENDIAN)
seq.foreach(buf.put(_, buffer))
buffer.array()
}
}
SeqUtils.toByteArray(Vector(1, 2, 3)).size
SeqUtils.toByteArray(Vector(1L, 2L, 3L)).size
Пересмотренный пример далее доступен в Scast ie.
Если вы хотите узнать больше о типовых классах, есть много материалов, доступных в Интернете, я обычно рекомендую это .