此外,请注意,这样的关键字中通常被称为 "命名空间" 的部分根本不需要是现有的命名空间。 正式的 Clojure 文档(例如在此页面上 https://clojure.org/reference/reader ) 称之为限定关键字,而在关键字名称中 '/' 前的部分是限定符。
这其中的一个原因是因为限定符可以是你的程序中的命名空间,但它根本不需要是一个命名空间。
在 Clojure/Java 中,所有关键字在运行时读取或动态创建时都被 'interned',这意味着所有具有相同名称的关键字在内存中都是相同的唯一 Java 对象。 为了实现这一点,所有关键字都存储在公共表中。 你可以在 Clojure 实现的 Java 文件 Keyword.java
中看到这一点,命名为 table
。 它是私有的,并且没有任何公共方法可以访问它,除了通过 intern
创建新的关键字,以及通过 find
检查是否有具有特定名称的关键字已被创建。
使用 Java 反射 API 绕过 private
限制相当直接,除非你的 JVM 是带有防止这种操作的安全选项启动的。 可以使用这些方法来访问该私有 table
字段的内容,遍历其所有条目,然后返回它们全部,然后您可以使用 Clojure 或 Java 代码过滤它们,仅保留您感兴趣的内容。
我对 ClojureScript 关键字的实现了解不够多,无法说清在那里什么是可能的。