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

如何在Scala中完全避免运行时反射?

发布时间:2020-12-16 18:34:59 所属栏目:安全 来源:网络整理
导读:请注意,这是一个社区帖子,应根据需要添加示例.如果您无法直接编辑添加示例(问题示例或解决方案)的答案,请在评论中发布带有要点(或类似内容)的链接或添加单独的答案,以便稍后进行集成. Scala 3可能根本不包含scala.reflect.runtime(Dotty目前没有,并且计划这
请注意,这是一个社区帖子,应根据需要添加示例.如果您无法直接编辑添加示例(问题示例或解决方案)的答案,请在评论中发布带有要点(或类似内容)的链接或添加单独的答案,以便稍后进行集成.

Scala 3可能根本不包含scala.reflect.runtime(Dotty目前没有,并且计划这样做不确定).虽然适用于Scala 2和Dotty的答案可能是转换目的和立即改进性能的首选,但也欢迎Dotty特定的解决方案.

参考

https://www.cakesolutions.net/teamblogs/ways-to-pattern-match-generic-types-in-scala

解决方法

一般建议

TypeTags在编译时生成(由于每个使用站点的宏扩展可能会产生大量的编译时间开销)并在运行时使用,也会产生一些潜在的运行时开销,具体取决于它们的使用的确切性质.因此,即使在Scala 2中,它们也许应该只是最后的手段(我们希望在这里解决所有这些问题,因此不需要最后的手段).相比之下,直接或间接使用instanceOf的东西非常快.

使用Java反射

instanceOf是super fast. classOf(即Java的getClass)几乎一样快.

使用ClassTag

ClassTag上的引用相等也应该非常快.

使用包装类型作为类型类的实例化

如果可能,您可能需要考虑将类型包装在类中,以赋予其具体的“Java”类型.虽然经常会有开销,但您可以使用value classes.

然后,包装类上的类型类通常是公开功能的好方法.顺便说一下,正如@Blaisorblade指出的那样,“类型标签只是一个无法无法的类型(使用方法typeName:String和tpe:Type)实例实现”.这带给我们下一个选择:

如果需要,使用宏

(目前Dotty不支持,但已计划)

虽然可能有点难以习惯,但最终结果应该是使用宏的代码比使用TypeTag时更清晰.此外,宏的使用远远超出TypeTag.

选定的例子

匹配集合的类型参数

TypeTag的一个典型用例,取自流行的帖子Scala: What is a TypeTag and how do I use it?,是对集合类型执行ad-hoc多态:

import scala.reflect.runtime.universe._

def meth[A : TypeTag](xs: List[A]) = typeOf[A] match {
  case t if t =:= typeOf[String] => "list of strings"
  case t if t <:< typeOf[Foo] => "list of foos"
}

scala> meth(List("string"))
res67: String = list of strings

scala> meth(List(new Bar))
res68: String = list of foos

与ClassTag不同,TypeTag是运行时反射.也许我在这里使用它错了,虽然这种行为非常令人惊讶.至少在REPL中,我没有收到以下任何警告:

def meth[A : ClassTag](xs: List[A]) = xs match {
  case xs: List[String] => "list of strings"
  case xs: List[Foo] => "list of foos"
}

meth(List(new Bar))   
res10: String = "list of strings"

这是来自@smarter on gitter(假设我们不需要分别处理不同类型的空列表):

def meth[A](xs: List[A]) = xs match {
   case Nil => "nil"
   case (_: String) :: _ => "list of strings"
   case (_: Foo) :: _ => 'list of foos"
}

这使用instanceOf,所以应该非常快.

(编辑:李大同)

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

    推荐文章
      热点阅读