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'参数访问,但函数享受它们关闭的任何环境)。
...