Scala的反射API

12

有人知道Scala的全功能反射API的状态吗?

我知道你可以使用Java的反射API来做一些简单的事情,但这在Scala的语言特性方面效果不佳。我找到了一篇有趣的文章,描述了一个实验性的Scala Mirroring API,但据我所知,这仍然是实验性的。我还发现提到了ScalaSigParser,但这似乎是相当低级的。

这更多的是出于好奇,因为我目前只是在玩Scala。我认为这个问题的答案可能对其他对Scala感兴趣的人也有用。


你能具体说明一下你想让反射做什么吗?你可以使用scala.tools.nsc中的例程来帮助进行名称混淆,有些东西不适合反射--你真的需要编译来帮助你,因为它们不仅仅是调用现有方法的问题(例如,如果你需要一个新的闭包)。 - Rex Kerr
首先,我认为创建类实例时使用命名参数会很好,这样您就不必担心参数的顺序 - 这可以替代JavaBean样式模式。我还认为能够查看类与Scala特性相关的结构会很好。即获取所有构造函数-找到主构造函数-调用它。或回答类似“此字段是val还是var”的问题。此外,最好使用符合惯用Scala风格的反射API,而不是返回到Java的API。只是想法... - Travis Schneeberger
我并没有考虑到一些更动态的元编程特性,比如在运行时添加方法或使用eval语句风格——只是更多地沿用了Java反射API所允许的操作方式,但是适应于Scala语言。 - Travis Schneeberger
相关内容 https://dev59.com/wGs05IYBdhLWcg3wDttn - Duncan McGregor
我刚刚在这里发布了关于新反射API的帖子 => http://alots.wordpress.com/ 我进行了演示,展示如何使用新的反射API来发现方法是否隐式。有一些链接直接指向Scala GitHub存储库。 - Alberto Souza
1个回答

6
“JavaBean风格模式的不可变替代方案”可以通过命名参数和可选的@BeanProperty注解来表达:
import reflect._
case class A(@BeanProperty val x: String, @BeanProperty val y : Int)

A(x = "s", y = 3)
A(y = 3, x = "s")

在静态类型语言中,添加方法(更确切地说是定义新接口)只有在客户端知道新方法并能针对接口进行编译时才有意义。使用结构化类型,客户端可以定义它们希望在对象中存在的方法。Scala编译器将把结构类型转换为反射代码,这可能会在运行时失败。
type T = {def go(x : Int): Int }
def y(any : Any) = any.asInstanceOf[T].go(2)

class A{
  def go(x : Int) = x + 1
}
y(new A())
y(new {}) //this will fail

你可以使用解释器即时定义新的类或特质。Interpret方法将Scala代码转换为字节码。
你已经提到了ScalaSigParser,它并不是很容易使用。
我认为你喜欢的其他功能目前还没有。

这在运行时失败是因为强制转换,而不是结构类型的原因。 - Jasper-M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接