Как получить карту имен полей с типами полей класса case с бесформенным - PullRequest
0 голосов
/ 22 ноября 2018

Я просмотрел почти все учебные пособия и у меня на столе есть «Астронавты типов», но я все еще не могу понять, как написать фрагмент, который может извлекать карту имен для типов, используя бесформенный из класса case.Если быть точным, я использую следующий интерфейс:

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

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

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

Помощь от любого, кто может помочь с написанием правильной реализации, будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Вы имели в виду нечто подобное?

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)
0 голосов
/ 22 ноября 2018

Я могу ошибаться, что 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] = Map(date -> java.time.LocalDate, id -> String)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...