如何在Scala中完全避免运行时反射?
请注意,这是一个社区帖子,应根据需要添加示例.如果您无法直接编辑添加示例(问题示例或解决方案)的答案,请在评论中发布带有要点(或类似内容)的链接或添加单独的答案,以便稍后进行集成.
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,所以应该非常快. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- twitter-bootstrap – Bootstrap.js,Bootstrap.min.js,Boot
- 为什么scala类需要显式扩展AnyRef
- WebService介绍(WebService基础知识、XFire、CXF(基于XFir
- 利用xfire编写webservice的例子
- ansible自动安装并配置ssh免密环境shell脚本
- Advanced Programming in UNIX Environment Episode 22
- scala – 非法继承,如何设计我的层次结构来创建我的UnitSpe
- Shell变量(五)
- twitter-bootstrap-3 – 在小scrn-Bootstrap推拉类或浮动修
- 如何在bash中组合timeout和eval命令