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*)

它被描述为一个映射,但它是以函数的方式调用的,所以我认为一个函数也应该可以工作。

感谢你快速的回答 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!
...