Scala 如何用shapeless获得case类字段名到字段类型的映射

Scala 如何用shapeless获得case类字段名到字段类型的映射,scala,generic-programming,shapeless,Scala,Generic Programming,Shapeless,我浏览了几乎所有的教程,并在我的办公桌上放了类型宇航员,但我仍然不知道如何编写代码片段,使用shapeless from case类将名称映射提取到类型。准确地说,我追求以下界面: case class Sample(id: String, date: LocalDate) def sampleExpectedMetadata = expectedMetadata[Sample] // = ("id" -> "String", "date" -> "LocalDate") def

我浏览了几乎所有的教程,并在我的办公桌上放了类型宇航员,但我仍然不知道如何编写代码片段,使用shapeless from case类将名称映射提取到类型。准确地说,我追求以下界面:

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

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

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

任何能够协助编写正确实施方案的人的帮助都将不胜感激。

我可能错了,Shapess与这种自省没有任何关系,使用来自并完善它的答案,您的答案将是:

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]=Mapdate->java.time.LocalDate,id->String

我可能错了,Shapeless与这种自省无关,使用来自并细化它的答案,您的答案将是:

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]=Mapdate->java.time.LocalDate,id->String

您有这样的想法吗

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
  }
}

你有这样的想法吗

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
  }
}