请在2024 Clojure 状态调查!分享您的想法。

欢迎!请参阅关于页面,了解更多关于这个功能的信息。

+1
编译器

Clojure中的关键字被缓存和互斥,以便

(identical? :a :a)

返回 true。但符号不是

(identical? 'a 'a)

返回 false。

有任何原因吗?

2 个回答

+4

选定
 
最佳答案

符号是上下文相关的,同一个符号的不同实例可以有不同的元数据。

元数据是有状态的,与内部化(interning)的概念天生对立。关键字没有元数据,但具有快速的标识相等语义。
0点赞

我认为答案的一部分是,关键字是为了更有效地使用内存和提高映射中的键查找性能而进行内部化的,因为Clojure中的大多数情况下,= 首先会进行快速的身份相等性检查(identical?),如果有相同的返回true。这使得它们在使用作为映射键时比其他值能提供更好的性能特性,因为在Clojure程序中,关键字经常被用作映射键。

当然,关键字内部化在首次内部化时会产生性能开销。这对于关键字来说通常不是一个大问题,特别是在大多数Clojure程序中,使用的关键字相对较少。对于人们读取海量JSON文件并将大量JSON键字符串转换为Clojure关键字的情况,这是一个性能问题。clojure在过去已经为此类的用例进行了改进。我现在没有JIRA票据,但如果有人感兴趣,我可以找到它们。

符号不是为了那些用法进行性能优化的,如果你尝试将它们用作映射中的键,性能可能会稍差一些,但我认为这也避免了在遇到新符号时的内部化性能开销。

在Common Lisp中存在一些类似的用例,以及可能的某些其他Lisp族语言。

...