Groovy如何以动态方式工作?

时间:2012-11-24 05:31:12

标签: dynamic compiler-construction groovy static

我为静态类型语言构建了一个小编译器。在理解了静态语言的工作原理之后,我无法理解像groovy这样的动态语言。

在构建我的编译器时,我知道一旦我生成了机器级代码,就无法改变它! (即其run-time)。

但是Groovy如何做这些神奇的事情,比如在语句中推断类型:

def a = "string"
a.size()

就我而言,groovy必须在运行a行之前找到string类型a.size()。它似乎在编译时(在构建AST时)这样做了!但这种语言被称为动态。

我很困惑,请帮助我弄清楚。

感谢。

1 个答案:

答案 0 :(得分:3)

Groovy并不是简单地“调用”一个方法,而是通过元对象协议调度它。方法调用将作为消息发送到对象,该对象可以响应或不响应。使用动态类型时,只有在响应该消息时,对象类型才无关紧要。这称为duck typing

您在反编译Groovy代码时可以看到它(虽然不容易)。您可以使用groovyc进行编译,并使用其他工具进行反编译。我推荐jd-gui。你不会看到显式调用的方法,因为Groovy的方法缓存(这样做是为了实现Groovy的整洁性能)。

对于像这样的简单脚本:

def a = "abcdefg"
println a.substring(2)

这将是生成的代码:

CallSite[] arrayOfCallSite = $getCallSiteArray(); Object a = "abcdefg";
return arrayOfCallSite[1].callCurrent(
    this, arrayOfCallSite[2].call(a, Integer.valueOf(2))); return null;

方法调用被“调度”到对象,而不是直接调用。这是与Smalltalks和Ruby方法调度类似的概念。正是由于这种机制,您可以拦截Groovy对象上的方法和属性访问。

从Groovy 2开始,Groovy代码可以静态编译,因此就像编译器一样。