gpt4 book ai didi

Scala案例类转换

转载 作者:行者123 更新时间:2023-12-05 00:15:56 25 4
gpt4 key购买 nike

当一个 case 类具有相同的字段并从相同的 trait 继承时,有没有一种方法可以将它们转换为另一个 case 类,而无需提供转换器函数(这只会进行一对一的字段映射)?

例如:

trait UberSomething {
val name: String
}
// these may be located in different files
case class Something(name: String) extends UberSomething
case class SomethingOther(name: String) extends UberSomething

val s = Something("wtv")
//s.asInstanceOf[SomethingOther] FAILS

最佳答案

首先永远不要定义trait成员(member)为 val如果它们打算在以后实现。

trait UberSomething {
def name: String
}
// these maybe in different files
case class Something(name: String) extends UberSomething
case class SomethingOther(name: String) extends UberSomething

import shapeless._, ops.hlist.Align

我之前在 Stackoverflow 某处看到的另一种方法是使用 Align 为窃取街头信誉而道歉。这样字段的顺序就无关紧要了。
class Convert[Target] {
def apply[Source, HLS <: HList, HLT <: HList](s: Source)(implicit

// Convert the Source to an HList type
// include field names, e.g "labelled"
// Shapeless "generates" this using an implicit macro
// it looks at our type, extracts a list of (Name, Type) pairs
genS: LabelledGeneric.Aux[Source, HLS],

// Convert the Target o an HList type
// include field names, e.g "labelled"
// So again we have a (Name, Type) list of pairs this time for Target
genT: LabelledGeneric.Aux[Target, HLT],

// Use an implicit align to make sure the two HLists
// contain the same set of (Name, Type) pairs in arbitrary order.
align: Align[HLS, HLT]
) = genT from align(genS to s)
}
// Small trick to guarantee conversion only requires
// a single type argument, otherwise we'd have to put something
// in place for HLS and HLT, which are meant to be path dependant
// and "calculated" by the LabelledGeneric.Repr macro so it wouldn't work as it breaches the "Aux pattern", which exposes a type member materialized by a macro in this case.
// HLT and HLS come from within genS.Repr and genT.Repr.
def convert[T] = new Convert[T]

这比 HList 好一点参数被很好地屏蔽为 apply 的一部分所以你不会绊倒自己。
val sample = Something("bla")
convert[SomethingOther](sample) // SomethingOther("bla")

让我们回顾一下这一行: genT from align(genS to s) .
  • 第一 genS to s转换 Source实例到 LabelledGeneric ,例如 HList与字段信息。
  • Align 对齐创建的 HList 的类型和字段为 Source键入以匹配 Target类型。
  • genT from ..允许我们创建 Target 的实例来自 HList授予编译器可以“证明”字段和类型“都在那里”,这是我们已经拥有的 Align .
  • 关于Scala案例类转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43371573/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com