gpt4 book ai didi

java - 协议(protocol)的 JVM Clojure 实现如何工作?

转载 作者:行者123 更新时间:2023-11-29 07:54:50 25 4
gpt4 key购买 nike

关于 Clojure 的文档 protocols声明为每个协议(protocol)生成相应的 Java 接口(interface)。但是,您可以使用协议(protocol)做的事情(将它们扩展为任意类型等)看起来不像任何在 Java 接口(interface)方面具有直接实现的东西。协议(protocol)和协议(protocol)方法在内部是如何工作的?为什么以及如何需要每个协议(protocol)的 Java 接口(interface)?

最佳答案

对 Clojure 平台源代码的简要检查揭示了:

  1. 对于每个协议(protocol)方法,都有一个哈希表,它从 Java Class 映射到为该 Class 实现协议(protocol)的 Clojure 函数。 (它实际上是一个名为 MethodImplCache 的自定义类的实例。)
  2. 当调用协议(protocol)方法的调度函数时,它获取第一个参数的 Class 并在哈希表中查找。
  3. 如果没有找到任何东西,它会遍历第一个参数的继承链,直到它找到一个查找成功的父类(super class)。然后在hashtable中插入dispatch Class,下次可以直接找到。
  4. 此外,任何时候查找成功,最近找到的 Class 及其对应的方法实现都缓存在一个实例变量中,如果分派(dispatch) Class< 则用于绕过哈希查找 下次也一样。
  5. 当协议(protocol)扩展到任意 Java 类时,生成的接口(interface)不会以任何方式发挥作用。如上所述,使用 MethodImplCache 解析对协议(protocol)方法的调用。
  6. 生成的接口(interface)用于当您使用reify 获取扩展协议(protocol)的匿名类的实例时,或者如果您使用deftypedefrecord 创建一个扩展协议(protocol)的新类。在任何一种情况下,您都会得到一个Class 的对象,它实现了生成的接口(interface)。
  7. 当 Clojure 编译器为调用协议(protocol)方法生成 JVM 字节码时,它会插入一些字节码来检查第一个参数是否是生成的接口(interface)的实例。如果是,它会使用普通的 Java 方法调用接口(interface)的适当方法。在那种情况下,我上面描述的协议(protocol)调度函数被完全绕过并且永远不会被调用。

这一切似乎都在暗示,当扩展到任意类时,协议(protocol)方法调用应该比普通的 Clojure 函数调用慢。如果您内联扩展协议(protocol),而不是单独调用扩展协议(protocol)扩展类型

关于java - 协议(protocol)的 JVM Clojure 实现如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18577289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com