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