scala – 在无形2.0中动态创建可扩展记录
发布时间:2020-12-16 08:55:56 所属栏目:安全 来源:网络整理
导读:我需要根据键的HList和值的映射生成可扩展的记录,这里是我想要实现的MWE(你可以在任何REPL中复制/粘贴这个,并且可以使用无形2.0,以便重现问题) import shapeless._; import syntax.singleton._; import record._case class Foo[T](column: Symbol)val cols =
我需要根据键的HList和值的映射生成可扩展的记录,这里是我想要实现的MWE(你可以在任何REPL中复制/粘贴这个,并且可以使用无形2.0,以便重现问题)
import shapeless._; import syntax.singleton._; import record._ case class Foo[T](column: Symbol) val cols = Foo[String]('column1) :: HNil val values = Map("column1" -> "value1") object toRecord extends Poly1 { implicit def Foo[T] = at[Foo[T]] { foo => val k = foo.column.name val v = values.get(k) (k ->> v) } } val r = cols.map(toRecord) // r: shapeless.::[Option[String] with shapeless.record.KeyTag[k.type,Option[String]] forSome { val k: String },shapeless.HNil] = Some(value1) :: HNil val value = r("column1") // error: No field String("column1") in record shapeless.::[Option[String] with shapeless.record.KeyTag[k.type,shapeless.HNil] val value = r("column1") 如果我尝试手动定义记录,一切都按预期工作 val q = ("column1" ->> Some("value1")) :: HNil // q: shapeless.::[Some[String] with shapeless.record.KeyTag[String("column1"),Some[String]],shapeless.HNil] = Some(value1) :: HNil q("column1") // Some[String] = Some(value1) 显然,区别在于,在一种情况下,KeyTag具有类型 KeyTag[String("column1"),Some[String]] 在(非工作)其他 KeyTag[k.type,Option[String]] forSome { val k: String } 我觉得问题是字符串k不是静态知道,但我不知道如何解决这个问题. 我担心答案是使用宏,但如果存在另一种解决方案,我会很高兴. 解决方法
如果您可以稍微更改Foo定义以允许它跟踪列键的单例类型(请注意我已删除未使用的T类型参数),这不是太糟糕:
import shapeless._; import syntax.singleton._; import record._ case class Foo[K <: Symbol](column: Witness.Aux[K]) val cols = Foo('column1) :: HNil val values = Map("column1" -> "value1") object toRecord extends Poly1 { implicit def atFoo[K <: Symbol] = at[Foo[K]] { foo => field[K](values.get(foo.column.value.name)) } } val r = cols.map(toRecord) 然后: scala> val value = r('column1) value: Option[String] = Some(value1) 请注意,我已将您的字符串键(“column1”)更改为符号,因为这是我们放入记录的内容. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |