2024 Clojure 状态调查!分享您的想法。

欢迎!有关此如何工作的更多信息,请参阅关于页面。

0
编译器

`
(ns field-test.core
(:import [java.util UUID]))

(defrecord UUIDWrapper [^UUID uuid])

(defn unwrap [^UUIDWrapper w]
(.-uuid w)) ; <- 无反射

(defn get-lower-bits [^UUIDWrapper w]
(-> w .-uuid .getLeastSignificantBits)) ; <- 反射 :(
`

编译器似乎拥有所需的所有信息,但lein check 打印

反射警告,field_test/core.clj:10:3 - 对java.lang.Object上的字段getLeastSignificantBits的引用无法解析。

(测试案例也位于 https://github.com/MichaelBlume/field-test)

4 答案

0

评论者:alexmiller

afaik,记录字段上的^UUID类型提示不会做任何事情。记录字段将是Object类型(只有^double和^long会影响到实际字段类型)。

更重要的是,使用Java互操作来检索记录的字段值是糟糕的做法。对于此,推荐使用关键字访问。

0

评论者:bronsa

相同的问题也适用于 tagging,其中关键字访问不是选项。

0
by

评论者:alexmiller

根据https://clojure.org/datatypes:"你应该始终按照协议或接口进行编程——
数据类型不能暴露其协议或接口中没有的方法"

沿着这个思路,通常是对于deftype,如果需要,我会生成一个适当的类型接口,然后让deftype实现该接口以暴露字段。

同时参照https://clojure.org/datatypes

"请注意,目前非原生类型的类型提示不会用于限制字段类型,也不会用于限制构造函数参数,但它将用于优化其在类方法中的使用"——也就是说,在实现记录/类型的内部方法中,引用字段应该有正确的提示。所以在上面的例子中,如果unwrap是记录/协议实现方法的接口,并且你引用了字段,你应该期望在这种情况下使用提示。

因此,我认为,根据设计,我们应该期望这个票据中描述的所有行为,这就是为什么我将这个重新分类为增强功能,而不是缺陷。

0
by
参考:https://clojure.atlassian.net/browse/CLJ-1774 (由michaelblume报告)
...