dynamic - Groovy 如何以动态方式工作?

标签 dynamic compiler-construction groovy static

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

在构建我的编译器时,我知道一旦生成机器级代码,就无法更改它! (即它的运行时)。

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

def a = "string"
a.size()

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

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

谢谢。

最佳答案

Groovy 并不简单地“调用”方法,而是通过元对象协议(protocol)调度它。方法调用作为消息发送到对象,对象可以响应也可以不响应。使用动态类型时,对象类型并不重要,只要它响应该消息即可。这称为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;

并且方法调用是“分派(dispatch)”给对象的,而不是直接调用。这与 Smalltalks 和 Ruby 方法调度类似。正是由于这种机制,您可以拦截 Groovy 对象上的方法和属性访问。

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

关于dynamic - Groovy 如何以动态方式工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13538571/

相关文章:

objective-c - 添加代码以动态阻止

performance - 空白何时会影响性能?

compiler-construction - WebAssembly 中如何管理堆内存?

Groovy + 将日志写入文件 + 使用注解注入(inject)日志

unit-testing - Grails:测试域对象约束

python - 切割杆问题集的递归树

json - Golang 使用动态相关键使用 json

sql - 如何将 T-SQL 中的结果连接到列中?

java - 以 Java 运行一个简单的文本文件

java - 在 Groovy 中模拟 HttpClient