加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – LabelledGeneric获取类名

发布时间:2020-12-16 18:05:59 所属栏目:安全 来源:网络整理
导读:我对Shapeless很新,因为我会从我的问题中推断出来.给定LabelledGeneric的实例,如何获取它所代表的类的名称.我可以从Keys获取字段名称信息,所以我假设我需要一些其他类型的Witness来封装类型本身,但我无法弄清楚哪个. 例如,如果我在包com.bar中有一个名为Foo
我对Shapeless很新,因为我会从我的问题中推断出来.给定LabelledGeneric的实例,如何获取它所代表的类的名称.我可以从Keys获取字段名称信息,所以我假设我需要一些其他类型的Witness来封装类型本身,但我无法弄清楚哪个.

例如,如果我在包com.bar中有一个名为Foo的case类,我想得到字符串“com.bar.Foo”(或单独就可以了).

implicit def example[T,Repr <: HList](implicit label: LabelledGeneric.Aux[T,Repr],kk: Keys[Repr]): Bibble[T] = new Bibble[T] {
  override def typeName(value: T): String = ???
}

解决方法

Shapeless的Generic为案例类和密封特征提供了产品总和表示,这意味着如果我们有一个像这样的简单ADT:

sealed trait Base
case object Foo extends Base
case class Bar(i: Int,s: String) extends Base

然后Generic [Base]将给我们一个映射到Foo.type :: Bar :: CNil-即.一个Foo.type或一个Bar(其中或者意味着我们在类型理论术语中讨论“sum类型”),Generic [Bar]给我们一个到Int :: String :: HNil的映射,这是Int和String(产品类型,其中“product”与标准库中scala.ProductN类型的含义大致相同).

LabelledGeneric使用产品总和表示的增强版本,其中product或sum中的每个术语都用标签标记.在密封特征的情况下,这些将是每个子类型的构造函数名称,对于案例类,它们将是成员名称.这些不是完全限定的名称 – 只是在本地消除歧义的标签.

Generic和LabelledGeneric不能用作编译时反射的通用工具.例如,它们不适用于任意类型,并且它们不提供对类型本身名称的访问.

您最好的选择可能是使用TypeTag,但如果您想要名称的类型级表示(如LabelledGeneric为标签提供),则需要使用宏生成的实例定义自己的类型类.像下面这样的东西应该工作:

import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context

trait TypeInfo[A] { type Name <: String; def name: String }

object TypeInfo {
  type Aux[A,Name0 <: String] = TypeInfo[A] { type Name = Name0 }

  def apply[A](implicit ti: TypeInfo[A]): Aux[A,ti.Name] = ti

  implicit def materializeTypeInfo[A,Name <: String]: Aux[A,Name] =
    macro matTypeInfoImpl[A,Name]

  def matTypeInfoImpl[A: c.WeakTypeTag,Name <: String](c: Context): c.Tree = {
    import c.universe._

    val A = c.weakTypeOf[A]
    val name = A.typeSymbol.name.decodedName.toString.trim

    q"new TypeInfo[$A] { type Name = ${ Constant(name) }; def name = $name }"
  }
}

但是,如果您只需要值级别的字符串,这对您的用例来说可能有些过分.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读