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

如何获得Scala 2.10反射引用的实际对象?

发布时间:2020-12-16 08:59:19 所属栏目:安全 来源:网络整理
导读:请考虑以下代码: object ResponseType extends Enumeration { val Listing,Album = Value} 我可以像这样得到指向这个对象的符号: import reflect.runtime.universe._val s = typeOf[ResponseType.Value].asInstanceOf[TypeRef].pre.typeSymbol 现在,有了这
请考虑以下代码:

object ResponseType extends Enumeration {
  val Listing,Album = Value
}

我可以像这样得到指向这个对象的符号:

import reflect.runtime.universe._
val s = typeOf[ResponseType.Value].asInstanceOf[TypeRef].pre.typeSymbol

现在,有了这个符号,我怎样才能获得实际的ResponseType对象?

解决方法

scala> val moduleClass = typeOf[ResponseType.Value].asInstanceOf[TypeRef].pre.typeSymbol
moduleClass: reflect.runtime.universe.Symbol = object ResponseType

scala> val module = moduleClass.owner.typeSignature.member(moduleClass.name.toTermName)
module: reflect.runtime.universe.Symbol = object ResponseType

scala> reflect.runtime.currentMirror.reflectModule(module.asModule).instance
res9: Any = ResponseType

现在,一些解释是有序的,因为这是一个非常模糊的实现细节,我们(还)!无法在公共API中进行抽象.

对于每个对象,Scala都会创建一个表示其签名的基础类,内部称为模块类.例如,如果编译对象C,编译器将生成C $.class.这正是模块类.

请注意,模块类与伴随类不同.比方说,对于案例类C,编译器将生成三个符号:类型C,术语C和(另一??个)类型C,其中第一个类型C表示类C(包含自动生成的副本,productPrefix,productArity等)和第二种类型C代表对象C的签名(包含自动生成的工厂,提取器等).不会有任何名称冲突,因为模块类没有直接添加到符号表中,只能通过< module> .moduleClass获得.

那么你实际从你的typeOf [ResponseType.Value]得到的.asInstanceOf [TypeRef] .pre.typeSymbol incantation是一个代表模块类的符号. API中没有任何功能可以让您从模块类中获取模块符号.在编译器内部肯定有一个,但我们决定不公开这个实现细节,因为它可能很快就会改变.

要访问源模块,您需要转到所有者,查看其成员列表,并查找与模块类具有相同名称的对象.这正是moduleClass.owner.typeSignature.member(moduleClass.name.toTermName)所做的.一个小小的警告是,如果在相同的范围内你有一个具有相同名称的方法,那么成员将返回一个重载的符号,你需要做类似.member(…)的东西.thisThat(_.isModule) .

之后,这是一块蛋糕.

编辑.实际上我们正在考虑引入ClassSymbol.module,它将返回模块类的源模块符号,否则返回NoSymbol.很可能这最终会在RC1中结束.按照发行说明进行操作

(编辑:李大同)

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

    推荐文章
      热点阅读