Clojure 2024状态调查中分享您的看法!

欢迎!请访问关于页面以了解更多关于如何使用本站的信息。

+2
Java Interop
重标记

这里有一些代码

(set! *warn-on-reflection* true)
(defrecord Foo [bar])
(.-bar (->Foo "bar"))

;;> Reflection warning, NO_SOURCE_PATH:1:1 - reference to field bar can't be resolved.
;;=> "bar"

正如我们所见,用于构建类型为 Foo 的记录的生成的 ->Foo 函数未提供类型提示,因此 Clojure 在进行互操作调用时会使用反射。

如果 Clojure 生成带有类型提示的构造函数那就更完美了。

1 个答案

+1

我几乎确定这个问题以前已经讨论过,并且被认为要么不如表面看起来那么有用,要么比表面看起来更复杂。我没有看到 jira 票,但它可能发生在其他论坛中。

我不认为这里提供的例子很有说服力——使用 :bar 进行关键字访问是期望的使用模式,它更简单、更便携、更受欢迎(且不需要类型提示)。

by
我并未表示不同意,只是我认为这并不是一个十分重要的问题。不确定如果这样做了,是否在野生的代码库中真的能看到任何明显的性能提升。

话虽如此,为了回答例子,也许字段访问是一个糟糕的选择,但如果记录实现了协议或接口,那么对这些方法的调用除非显式类型提示,否则也会是反射的。这可能会是一个更常见的使用场景。
by
我会被一个令人信服的例子所感动。 :)  

协议调用不具有反射性 - 那些总是在调用地点进行运行时类型检查。接口,可能相关。
by
那么对于deftype呢?它不支持关键字访问?我目前正在一个我继承的代码库中遇到字段访问的反射警告。

我搜索了关于这个主题的邮件列表和Clojurians存档,但没有找到任何解释为什么位置工厂函数不能进行类型提示的内容。
...