【问题标题】:Unwrap/strip Shapeless Coproduct objects展开/剥离无形副产品对象
【发布时间】:2017-09-12 12:33:32
【问题描述】:

我有一个如下所示的域:

package object tryme {
  type ALL = AlarmMessage :+: PassMessage :+: HeyMessage :+: CNil
}
import com.tryme._

trait PayloadKind
trait Command extends PayloadKind
trait Event extends PayloadKind

trait Message[+T <: PayloadKind] {
  val id: String
  val payload: T
}

case class Alarm(severity: Int) extends Event
case class Pass(reason: String) extends Event
case class Hey(order: String) extends Command

case class AlarmMessage(id: String, payload: Alarm) extends Message[Event]
case class PassMessage(id: String, payload: Pass) extends Message[Event]
case class HeyMessage(id: String, payload: Hey) extends Message[Command]

case class AvroMessage(
    id:    String,
    cargo: ALL
)

如果我使用 cargo = HeyMessage 创建一个 AvroMessage,我就能够成功地对其进行序列化/反序列化。

当我检查反序列化的 AvroMessage 对象的 cargo 字段时,它看起来像这样:

Inr(Inr(Inl(HeyMessage(art333,Hey(wow)))))

在 Shapeless 中,我如何解开/剥离所有 Inr/Inls?理想情况下,如果可以避免的话,我不想关心(反序列化后)有效负载是 HeyMessage (或任何其他类型)。我要将货物投射到 Message[PayloadKind],但首先我需要打开它。

(我看到了类似问题here 的答案,但我承认我不明白它是如何工作的,也无法适应它。)

【问题讨论】:

    标签: scala shapeless


    【解决方案1】:

    你可以使用shapeless.ops.coproduct.Selector

    val coproduct = Inr(Inr(Inl(HeyMessage(art333, Hey(wow)))))
    Selector[ALL, HeyMessage].apply(coproduct).get
    

    结果是HeyMessage(art333,Hey(wow))

    https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/coproduct.scala#L41-L60

    【讨论】:

      【解决方案2】:

      您可以使用来自syntax 子包的扩展方法:

      import shapeless.syntax._
      // select returns an Option
      coproduct.select[HeyMessage].get
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多