【问题标题】:How to get map of field names to field types of case class with shapeless如何使用无形将字段名称映射到案例类的字段类型
【发布时间】:2018-11-23 06:25:55
【问题描述】:

我浏览了几乎所有的教程,并在我的桌子上放了“The Type Astronauts”,但我仍然不知道如何编写 sn-p,它可以使用 case class 中的 shapeless 提取名称映射到类型。准确地说,我在关注以下界面:

case class Sample(id: String, date: LocalDate)

def sampleExpectedMetadata = expectedMetadata[Sample] // = ("id" -> "String", "date" -> "LocalDate")

def expectedMetadata[T]: Map[String, String] = ???

非常感谢任何可以帮助编写正确实现的人。

【问题讨论】:

    标签: scala generic-programming shapeless


    【解决方案1】:

    你有这样的想法吗?

    import shapeless._
    import shapeless.record._
    import shapeless.labelled._
    
    object expectedMetadata {
      def apply[T](implicit g: GetFieldTypes[T]): Map[String, String] = g.getFieldTypes
    
      sealed trait GetFieldTypes[T] {
        def getFieldTypes: Map[String,String]
      }
    
      implicit val hnil = new GetFieldTypes[HNil] {
        def getFieldTypes = Map.empty
      }
    
      implicit def hcons[K <: Symbol, V, T <: HList](implicit
        wit: Witness.Aux[K],
        typ: Typeable[V],
        rest: GetFieldTypes[T]
      ) = new GetFieldTypes[FieldType[K, V] :: T] {
        def getFieldTypes = rest.getFieldTypes + (wit.value.name -> typ.describe)
      }
    
      implicit def caseClass[T, G](implicit
        lg: LabelledGeneric.Aux[T, G],
        rest: GetFieldTypes[G]
      ) = new GetFieldTypes[T] {
        def getFieldTypes = rest.getFieldTypes
      }
    }
    

    使用示例:

    scala> case class Sample(id: String, date: LocalDate)
    scala> expectedMetadata[Sample]
    res1: Map[String,String] = Map(date -> LocalDate, id -> String)
    

    【讨论】:

      【解决方案2】:

      我可能错了,Shapeless 与这种内省无关,使用来自 Get field names list from case class 的答案并对其进行改进,您的答案将是:

      import scala.reflect.runtime.universe._
      
      def expectedMetadata[T](implicit t:TypeTag[T]):Map[String, String] = 
         t.tpe.members
          .collect { case m:MethodSymbol if m.isCaseAccessor => m }
          .map(x => x.name.toString -> x.returnType.toString)
          .toMap
      

      在哪里,expectedMetadata[Sample] 将返回 Map[String,String] = Map(date -&gt; java.time.LocalDate, id -&gt; String)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-02
        • 1970-01-01
        • 1970-01-01
        • 2012-04-02
        • 2018-07-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多