8.1 创建哈希表

创建哈希表的主要函数是 make-hash-table

Function: make-hash-table &rest keyword-args

该函数根据指定的参数创建一个新的哈希表。参数应由关键字(专门识别的特定符号)与对应的值交替组成。

make-hash-table 支持多个关键字,但你真正需要了解的只有两个::test:weakness

:test test

指定该哈希表的键查找比较方式。默认值为 eql,其他可选值为 eqequal

eql

如果键是数字,当它们满足 equal 时视为相同,即数值相等,且同为整数或同为浮点数;否则,两个不同的对象永远不相同。

eq

任意两个不同的 Lisp 对象,作为键时都视为不同。

equal

如果两个 Lisp 对象按照 equal 函数判定为相等,则它们作为键时视为相同。

你可以使用 define-hash-table-test(see 定义哈希表比较方式)为 test 定义更多可选的比较方式。

:weakness weak

哈希表的 “弱引用(weakness)” 属性用于指定:哈希表中键(key)或值(value)的存在,是否会阻止它们被垃圾回收(garbage collection)。

参数 weak 的取值必须是 nilkeyvaluekey-or-valuekey-and-value 之一,其中 tkey-and-value 的别名。若 weak 设为 key,则哈希表不会阻止其键被垃圾回收(前提是这些键在其他地方无引用);当某个键被回收时,对应的键值对会从哈希表中移除。

weak 设为 value,则哈希表不会阻止其值被垃圾回收(前提是这些值在其他地方无引用);当某个值被回收时,对应的键值对会从哈希表中移除。

weak 设为 key-and-valuet,则只有当键和值都处于 “存活” 状态时,对应的键值对才会被保留。因此,哈希表既不会保护键、也不会保护值免于垃圾回收;只要键或值任意一方被回收,该键值对就会被移除。

如果 weakkey-or-value,那么键或值其中任意一个存活,就能保留该键值对。因此,只有当键和值都将被垃圾回收时(若非因为弱哈希表的引用),对应的键值对才会从哈希表中移除。

weak 的默认值为 nil,此时哈希表中的所有键和值都会被保护,不会被垃圾回收。

:size size

该参数用于提示你计划在哈希表中存放多少个键值对。如果你知道大致数量,通过该参数指定可以略微提升效率;但由于哈希表内存是自动管理的,这种速度提升通常并不显著。

你还可以使用哈希表的打印表示形式来创建哈希表。只要指定哈希表中的每个元素都有合法的读取语法(see 打印表示与读入语法),Lisp 读取器就能解析这种打印表示。 例如,下面的表达式定义了一个哈希表,其中包含键 key1key2(均为符号),分别对应值 val1(符号)和 300(数字)。

#s(hash-table data (key1 val1 key2 300))

需要注意的是,在 Emacs Lisp 代码中使用这种方式时,是否会创建新的哈希表是未定义行为。如果你希望创建新的哈希表,应当始终使用 make-hash-table 函数(see 自求值形式)。

哈希表的打印表示形式以 ‘#s’ 开头,其后紧跟一个以 ‘hash-table’ 为首元素的列表。列表的其余部分由零个或多个 “属性 - 值” 对组成,用于指定哈希表的属性和初始内容。这些属性与值会按字面量读取。合法的属性名包括 testweaknessdata:其中 data 属性应是一个包含键值对的列表,用于设定哈希表的初始内容;其余属性的含义与上文所述 make-hash-table 函数的对应关键字(:test:weakness)完全一致。

注意:你不能直接指定初始内容中包含无读取语法的对象(例如缓冲区、窗口框架)的哈希表。这类对象可以在哈希表创建之后再添加进去。


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike