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

欢迎!请参阅 关于 页面以获取更多该功能的信息。

+1 投票
Clojure

大家好!我不太确定这是否是错误,所以我将它报告在这里并询问“这是否是预期的?”

似乎 defrecorddeftype 表达式没有访问它们词法闭包中的绑定。以下两个类型声明在 Clojure 1.10.1 中都会失败,显示“无法解决符号:x 在这个上下文中”的错误。

(defprotocol ID
  (id [x] x))

(let [x 10]
  (deftype TType []
    ID
    (id [_] x)))

(let [x 10]
  (defrecord TRecord []
    ID
    (id [_] x)))

幸会!

1 个答案

0 投票

已被选中
 
最佳答案

这是预期的,不是错误——这在 deftype 文档字符串中有说明。

现在我明白了!谢谢,这是一条给未来看到这条信息的人的相关评论:

请注意,方法体不是闭包,局部环境只包含命名字段,可以直接访问这些字段。
但是


    (defprotocol ID
        (id [x] x))
    
      (let [x 42
            f (fn [_] x)]
        (extend
         java.util.Properties
          ID
          {:id f}))

      (id (java.util.Properties.))
      ;; => 42
问题是关于deftype/defrecord方法,所以不确定这与此有什么关系。
通过"extend"附加的方法会关闭其环境。因此,您可以选择是否在deftype内部逐词声明协议实现(在这种情况下,类型的成员在方法的環境中),或者使用extend(在这种情况下,成员只能通过"this"参数访问,但函数可以享受它们关闭的环境)。
...