Получить имя и тип поля класса дела с бесформенным - PullRequest
0 голосов
/ 04 апреля 2019

Можно ли получить имена и типы полей класса дел в scala с бесформенными?

Я пробовал вот так (T - это дело):

trait Cpo[T] {

def withPrimaryKey[R <: HList, K, V <: HList](f: Seq[Symbol] => Seq[Symbol])(
    implicit labellGeneric: LabelledGeneric.Aux[T, R], keys: Keys.Aux[R, K],
    ktl: hlist.ToList[K, Symbol]): Cpo[T]
}

, но я могу толькополучить имя поля.

Zlaja

Ответы [ 3 ]

2 голосов
/ 04 апреля 2019

Попробуйте

object typeablePoly extends Poly1 {
  implicit def default[A](implicit typeable: Typeable[A]): Case.Aux[A, String] = at(_ => typeable.describe)
}

trait Cpo[T] {

  def withPrimaryKey[R <: HList, K <: HList, V <: HList, V1 <: HList](f: Seq[Symbol] => Seq[Symbol])(implicit
    labellGeneric: LabelledGeneric.Aux[T, R],
    keys: Keys.Aux[R, K],
    ktl: hlist.ToList[K, Symbol],
    values: Values.Aux[R, V],
    mapper: hlist.Mapper.Aux[typeablePoly.type, V, V1],
    vtl: hlist.ToList[V1, String]
  ): Cpo[T] 
}

Теперь ktl дает список имен полей (как Symbol с), а vtl дает список типов полей (как String с).


Попробуйте

  object typeablePoly extends Poly1 {
    implicit def default[A](implicit typeable: Typeable[A]): Case.Aux[A, String] = at(_ => typeable.describe)
  }

  object nullPoly extends Poly0 {
    implicit def default[A]: ProductCase.Aux[HNil, A] = at(null.asInstanceOf[A])
  }

  trait Cpo[T] {

    def withPrimaryKey[R <: HList, K <: HList, V <: HList, V1 <: HList](f: Seq[Symbol] => Seq[Symbol])(implicit
      labellGeneric: LabelledGeneric.Aux[T, R],
      keys: Keys.Aux[R, K],
      ktl: hlist.ToList[K, Symbol],
      values: Values.Aux[R, V],
      mapper: hlist.Mapper.Aux[typeablePoly.type, V, V1],
      fillWith: hlist.FillWith[nullPoly.type, V],
      vtl: hlist.ToList[V1, String]
    ): Cpo[T] = {
      println(ktl(keys())) // List('i, 's)
      println(vtl(mapper(fillWith()))) // List(Int, String)
      ???
    }
  }

  case class MyClass(i: Int, s: String)
  new Cpo[MyClass] {}.withPrimaryKey(identity)
0 голосов
/ 05 апреля 2019

Если в использовании бесформенного нет необходимости, вы можете получить тип и значение, используя класс Product в scala

case class Test(x:Int,y:String,z:Boolean)
println(getGeyNameValueType(Test(1,"a",true)).foreach(println))

def getGeyNameValueType(inp: Product): Iterator[(Any, Class[_])] = {
    val itr = inp.productIterator
    for {
      item <- itr
    } yield (item, item.getClass)
}

Выходные данные

(1,class java.lang.Integer)
(a,class java.lang.String)
(true,class java.lang.Boolean)
()
0 голосов
/ 04 апреля 2019

Вы определенно можете получить имена полей.Например, здесь вы можете найти, как написать свой универсальный механизм деривации на основе бесформенной формы: Биты бесформенной детали 2 .Более конкретно, вы должны взглянуть на Часть получения классов Class , есть функция, которая выводит кодировщик для произвольного класса case, ее сигнатура:

implicit def hconsToJson[Key <: Symbol, Head, Tail <: HList](
    implicit key: Witness.Aux[Key],
    headWrites: JsonWrites[Head],
    tailWrites: JsonWrites[Tail])
    : JsonWrites[FieldType[Key, Head] :: Tail] = ???

Следовательно, параметр key позволяетВы получите доступ к имени поля определенного поля.Для типов единственный известный мне способ - использовать рефлексию.Прочитайте это для подробностей Руководство по Scala для типов тегов .

...