顺便说一句,虽然通常所说的“命名空间”部分不需要是一个真正的命名空间,因为官方 Clojure 文档(例如在这个页面 https://clojure.org/reference/reader )称它们为限定符关键词,并且在关键词名称中 '/' 前面的部分是限定符。
其中一个原因是,虽然限定符可以与程序中的命名空间相同,但它根本就不需要是一个命名空间。
在 Clojure/Java 中,所有关键词都属于 'interned',即在运行时读取或动态创建时,意味着所有具有相同名称的关键词都是内存中相同的唯一 Java 对象。为了实现这一点,所有关键词都存储在公共表中。您可以在 Clojure 实现中名为 Keyword.java
的 Java 文件中看到这一点,名为 table
。它被声明为 private,并且没有公共方法可以访问它,除了通过 intern
创建新的关键词和 find
来查看是否已创建具有特定名称的关键词。
使用 Java 反射 API 穿越这个 private
限制相当简单,除非您的 JVM 是在阻止此操作的安全选项启动的。可以使用这些方法访问私有 table
字段的 内容,遍历其所有条目,并返回它们所有,然后可以使用 Clojure 或 Java 代码过滤它们,只保留您感兴趣的内容。
我对 ClojureScript 关键词的实现了解不多,无法说在这里可以实现什么。