评论者:alexyakushev
我尝试了 (链接: ~alexmiller) 建议的实现。这个附加的补丁使用 getComponentType 而不是字符串魔法,并且与第一个补丁相比引入了以下改进
- 现在也支持 set。除了最后一个索引以外的所有索引都展开为 RT.aget 调用,最外层的调用展开为 RT.aset。
- 如果内联版本在任何时候都无法解析数组的类型,那么,它将不会展开成 N 个 RT.aget 调用(这将产生 N 个编译器反射点),而是生成对非内联 aget 调用的调用,该调用将使用 Array.get(这更快)。
缺点是,现在多参数的 set 调用在编译器反射中触发,而以前这是 Array.set。我怀疑是否有必要对这些角落进行平滑处理,或者是否实际上更偏好在这些情况下反映更明显(显示在编译器警告中)。
我还附加了验证示例的 REPL 日志(使用 clj-java-decompiler)。把它转换成测试会很好,但我还不知道如何做到这一点。
顺便说一下,我不得不使用 {{((var aget) ...)}} 恶搞来强制调用非内联版本。我并不喜欢它,但我还没有想出什么更好的方法。另一种方式是将非内联版本分离成一个单独的私有函数,但我不想在核心命名空间中添加更多的 Vars。