Может ли scala неявно объединить 2 имплицита в неявный кортеж? - PullRequest
2 голосов
/ 28 апреля 2020

Контекст:
Я пытаюсь работать с RandomAccessFile Java, и я хочу иметь возможность читать / писать что-либо с неявным fixedBytable:

case class FixedBytable[T](private val size: Int,
                           private val read: ByteBuffer => T,
                           private val write: (T, ByteBuffer) => Unit)

Я определил FixedBytable для всех базовых c byte / short / float / ..., что прекрасно работает. Я также смог определить tuple_Bytable для всех типов кортежей, которые могут объединять 2 (или кортеж любого размера) FixedBytable в 1, которые могут читать / записывать кортеж «children» (например: FixedBytable[(Int, Int)].

Вопрос:
Можете ли вы сделать это неявно? Может быть, я формулирую это неправильно, но есть ли способ сказать, что, если вы можете неявно найти FixedByable[A] и FixedBytable[B] , то вы должны знать, как неявно найти FixedBytable[(A, B)]?

1 Ответ

2 голосов
/ 28 апреля 2020

Вот решение, чтобы заставить мою проблему работать, надеюсь, вы сможете абстрагировать ее от любой ситуации.
Суть в том, что вам нужны и implicit def, и implicit в начале параметров.

/*
Note:
implicit def
implicit b1: ...
*/

implicit def tuple2Bytable[T1, T2](implicit b1: Bytable[T1], b2: Bytable[T2]): Bytable[(T1, T2)] =
  Bytable[(T1, T2)](
    b1.size + b2.size,
    bb => {
      val v1: T1 = b1.fromBytes(bb)
      val v2: T2 = b2.fromBytes(bb)
      (v1, v2)
    },
    (t, bb) => {
      b1.toBytes(t._1, bb)
      b2.toBytes(t._2, bb)
    }
  )

implicit def tuple3Bytable[T1, T2, T3](implicit b1: Bytable[T1], b2: Bytable[T2], b3: Bytable[T3]): Bytable[(T1, T2, T3)] =
  Bytable[(T1, T2, T3)](
    b1.size + b2.size + b3.size,
    bb => {
      val v1: T1 = b1.fromBytes(bb)
      val v2: T2 = b2.fromBytes(bb)
      val v3: T3 = b3.fromBytes(bb)
      (v1, v2, v3)
    },
    (t, bb) => {
      b1.toBytes(t._1, bb)
      b2.toBytes(t._2, bb)
      b3.toBytes(t._3, bb)
    }
  )
...