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

欢迎!有关此如何运作的更多信息,请参阅 关于 页面。

+3
文档
编辑

hash-map 的文档字符串表示它返回一个哈希映射。
但是,有一个无参数的参数,它返回一个空的 数组 映射。

因此,文档和实现之间存在差异。

1 答案

0

这里的混淆点是“持久哈希映射”是这里的抽象,但有两个具体的实现:hash-map(PersistentHashMap)和array-map(PersistentArrayMap),后者的类型根据映射大小转变为前者。

hash-map 是持久哈希映射抽象的构造函数(通用),不保证返回的具体类型。然而,array-map 是(明确地)数组映射的构造函数。没有为 PersistentHashMap 显式地提供构造函数。

如果我听到你说这里的抽象是“持久化映射”,我可以理解。但是“持久化哈希映射”则不然。

究竟是什么让数组映射成为哈希表的实现?在任何地方都没有找到关于它的提及(参考资料中确实明确地将数组映射作为独立的事物提及),并且实现没有使用哈希,这是意料之中的。而且从概念上讲,数组映射和哈希映射之间的关系仅在于它们都是映射。

即使我避免检查调用这类映射的 `(type ...)` 的结果,但“哈希映射”这一词语还是会有一个预设——将使用哈希函数。有人可能会说这根本不重要,我同意这几乎适用于所有情况,但在调试与哈希和映射相关的内容时,这肯定会令人困惑。

更令人困惑的是,尽管现在几乎已经变成了常识,知道具有8项以上的映射字面量是哈希映射,但 `(hash-map 1 2)` 返回的却是哈希映射,而不是数组映射。

还有其他区别。至少,`print-dup` 只为 `PersistentHashMap` 定义,而不是 `PersistentArrayMap`,这会导致一些意想不到的事情,比如 `#=(clojure.lang.PersistentArrayMap/create {})`。
好吧,“持久化映射”更公平,重要的类型是 IPersistentMap。

你是如何得到最后一个例子的?`pr` 或 `print` 都不会给你这个结果。
使用 `(binding [*print-dup* true] (prn {}))`。
...