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投票
by
selected by
 
最佳答案

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

by
现在我看到了!谢谢,下面是这个问题的相关评论供后来者参考

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


    (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' 参数访问,但函数可以享受它们捕获的环境)。
...