加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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”)更改为符号,因为这是我们放入记录的内容.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读