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

据我所知,记录字段上的 ^UUID 类型提示没有任何作用。记录字段将具有类型 Object(只有 ^double 和 ^long 会影响实际字段类型)。

也许更重要的是,使用 Java 互操作来获取记录的字段值是不良的做法。应为该场景首选使用关键字访问。

0

评论者:bronsa

同样的问题适用于没有关键字访问选项的 deftypes。

0

评论者:alexmiller

根据https://clojure.org/datatypes:“你应该始终针对协议或接口进行编程 -
数据类型不能公开协议或接口中未定义的方法。

沿着这个方向,通常对于 `deftype` 类型,如果需要,我会生成一个包含适当类型的接口,然后让 `deftype` 实现该接口以公开字段。

也请参阅 https://clojure.org/datatypes

"注意,目前非原始类型的类型提示将不会用于约束字段类型或构造函数参数,但将用于优化其在类方法中的使用" —— 也就是说,在实现记录/类型的某个方法内部,引用字段时应使用正确的提示。因此,在上面的例子中,如果 `unwrap` 是记录的接口或协议实现方法,并且你引用了字段,你应该期望在这个情况下使用该提示。

因此,我的看法是,根据设计,应该期望此票据中描述的所有行为,这也是为什么我将其重新分类为一个增强,而不是一个缺陷。

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