通用#到,但有字段名称?

Kev*_*ith 3 scala shapeless

使用Generic#to,我可以得到一个HList代表case class:

import shapeless._
case class F(x: Int, y: String)

scala> Generic[F].to( F(1, "foo") )
res1: shapeless.::[Int,shapeless.::[String,shapeless.HNil]] = 
    1 :: foo :: HNil
Run Code Online (Sandbox Code Playgroud)

但是,我想得到以下表示:

("x", 1) :: ("y", "foo") :: HNil

换句话说,而不是只是F实例的字段的值,我想获得字段名,即xy,以及.

我怎样才能得到这种表述?

Gab*_*lla 5

你在找LabelledGeneric.

为了打印字段,您可以使用Fields类型类(来自ops.record包),.fields如果您也导入包,则可以调用该类record.

这是一个完整的例子

import shapeless._, record._, ops.record._
case class F(x: Int, y: String)    

scala> LabelledGeneric[F].to(F(1, "foo")).fields
res1: shapeless.::[(Symbol with shapeless.tag.Tagged[String("x")], Int),shapeless.::[(Symbol with shapeless.tag.Tagged[String("y")], String),shapeless.HNil]] = ('x,1) :: ('y,foo) :: HNil
Run Code Online (Sandbox Code Playgroud)

如果您还想将密钥转换为String:

object keysToString extends Poly1 {
  implicit def keyToName[A, B] = at[(Symbol with A, B)] { case (k, v) => (k.name, v) }
}

scala> LabelledGeneric[F].to(F(1, "foo")).fields.map(keysToString)
res2: shapeless.::[(String, Int),shapeless.::[(String, String),shapeless.HNil]] = (x,1) :: (y,foo) :: HNil
Run Code Online (Sandbox Code Playgroud)