我正在使用Scrooge生成类。它们看起来像这样,这里有一个例子:
object Flags extends ThriftStructCodec3[Flags] {
private val NoPassthroughFields = immutable$Map.empty[Short, TFieldBlob]
val Struct = new TStruct("Flags")
val IsDangerousField = new TField("isDangerous", TType.BOOL, 1)
val IsDangerousFieldManifest = implicitly[Manifest[Boolean]]
val IsWildField = new TField("isWild", TType.BOOL, 2)
val IsWildFieldManifest = implicitly[Manifest[Boolean]]
def apply(
isDangerous: Option[Boolean] = None,
isWild: Option[Boolean] = None
): Flags =
new Immutable(
isDangerous,
isWild
)
def unapply(_item: Flags): Option[scala.Product2[Option[Boolean], Option[Boolean]]] = Some(_item)
object Immutable extends ThriftStructCodec3[Flags] {
override def encode(_item: Flags, _oproto: TProtocol) { _item.write(_oproto) }
override def decode(_iprot: TProtocol): Flags = Flags.decode(_iprot)
}
/**
* The default read-only implementation of Flags. You typically should not need to
* directly reference this class; instead, use the Flags.apply method to construct
* new instances.
*/
class Immutable(
val isDangerous: Option[Boolean],
val isWild: Option[Boolean],
override val _passthroughFields: immutable$Map[Short, TFieldBlob]
) extends Flags {
def this(
isDangerous: Option[Boolean] = None,
isWild: Option[Boolean] = None
) = this(
isDangerous,
isWild,
Map.empty
)
}
}
trait Flags
extends ThriftStruct
with scala.Product2[Option[Boolean], Option[Boolean]]
with java.io.Serializable
{
import Flags._
def isDangerous: Option[Boolean]
def isWild: Option[Boolean]
def _passthroughFields: immutable$Map[Short, TFieldBlob] = immutable$Map.empty
def _1 = isDangerous
def _2 = isWild
override def productArity: Int = 2
override def productElement(n: Int): Any = n match {
case 0 => this.isDangerous
case 1 => this.isWild
case _ => throw new IndexOutOfBoundsException(n.toString)
}
override def productPrefix: String = "Flags"
}
目的是使用 Shapeless 从这些类生成嵌套地图,对其进行一些操作,然后将地图转换回节俭生成的类。
使用Shapeless将嵌套案例类转换为嵌套地图并使用Shapeless将 Map[String,Any] 转换为案例类 除了堆栈溢出响应中提供的示例之外,我还为 Option[A] 实现了隐式。
现在,因为 Scrooge 没有生成正确的案例类,我试图改用 Immutable 类(例如Flags.Immutable
)。这样做意味着我必须为所有 thrift 类定义隐式,以将它们转换为NameOfClass.Immutable
. 到目前为止,一切都很好。
但是我有两件事我似乎没有做对(完整的实现可以在ClassToMap.scala
文件中找到):
(1) 从节俭类生成地图时,隐式选项似乎被忽略了。
implicit def hconsToMapRecOption[K <: Symbol, V, R <: HList, T <: HList]
(implicit
wit: Witness.Aux[K],
gen: LabelledGeneric.Aux[V, R],
tmrT: Lazy[ToMapRec[T]],
tmrH: Lazy[ToMapRec[R]]
): ToMapRec[FieldType[K, Option[V]] :: T] = new ToMapRec[FieldType[K, Option[V]] :: T] {
override def apply(l: FieldType[K, Option[V]] :: T): Map[String, Any] = {
tmrT.value(l.tail) + (wit.value.name -> l.head.map(value => tmrH.value(gen.to(value))))
}
}
(2) 在处理节俭工会时,我的隐式没有被使用。
implicit def hconsToMapRecGoatData[K <: Symbol, R <: HList, T <: HList]
(implicit
wit: Witness.Aux[K],
gen: LabelledGeneric.Aux[MyGoat, R],
tmrT: Lazy[ToMapRec[T]],
tmrH: Lazy[ToMapRec[R]]
): ToMapRec[FieldType[K, MyGoatData] :: T] = new ToMapRec[FieldType[K, MyGoatData] :: T] {
override def apply(l: FieldType[K, MyGoatData] :: T): Map[String, Any] = {
tmrT.value(l.tail) + (wit.value.name -> tmrH.value(gen.to(l.head.goat)))
}
}
我没有花太多时间查看映射到类的实现,但我认为它应该反映类以映射一个。