请在 2024 年 Clojure 调查中分享您的想法!

欢迎!请在 关于 页面了解有关工作原理的更多信息。

0
tools.reader
重新标记

我使用 clojure.tools.reader/read 读取文件中的 clojure 和 cljs 表达式。

一切正常,但是当读取像 ::keyword 这样的命名空间关键词时,它们被读取为 :user/keyword。

我知道读取器使用 ns 动态变量来找出读取符号和关键词的当前命名空间,但我不知道如何使用它来读取不存在于命名空间,例如当前正在读取的文件中的命名空间。

我在执行读取之前尝试了一个 (in-ns file-ns-symbol),这样它就会在读取之前创建命名空间,并可以正常工作,但有时我会遇到 java.lang.IllegalStateException: Can't change/establish root binding of: *ns* with set 错误。

仅仅执行

(binding [*ns* file-ns-symbol]
  (reader/read ...))

是不行的,因为它将尝试对不存在的命名空间调用 (the-ns file-ns-symbol)。

有什么想法或提示吗?

谢谢!

1 答案

+1

选中答案
 
最佳答案

如果您知道如何处理自动解决的键别名,则可以设置动态绑定 *alias-map* 并将其插入到其中:[http://clojure.github.io/tools.reader/#clojure.tools.reader/*alias-map*](http://clojure.github.io/tools.reader/#clojure.tools.reader/*alias-map*)

它被描述为一个映射,但它是作为一个函数调用的,因此我认为一个函数也可以。

感谢您的快速回复 Alex,并且是的,我已经在使用 *alias-map* 作为函数,但这只能处理 ::alias/key 的情况,我的问题在于应该解析为当前命名空间的情况。
对了,别名映射只会与别名一起使用。您可以使用 create-ns 实际上创建命名空间吗?

    user=> (create-ns 'x)
    #object[clojure.lang.Namespace 0x4397a639 "x"]
    user=> (binding [*ns* (find-ns 'x)] (r/read-string "::foo"))
    :x/foo
好的,这就是我一直在寻找的 create-ns,它工作得很好!再次感谢 Alex!
...