EmacsElispCharTable

Char Table

char-table 和 vector 十分相似。不同点是,char-table 字符编码作为数组的下标。可以 使用 aset , aref 来访问 char-table 。 除此之外, char-table 还有一个额外的空间, 叫做 extra slots ,可以存储其他的 Emacs Lisp object 。

char-table 可以有 subtype ,这个 subtype 是一个 symbol 。subtype 有两个目的: 区 分 char-table 的不同用法,控制有多少个 extra slots 可以使用。 例如 display table 是一个 char-table , 他的 subtype 是 diaplay-table 。 syntax table 的 subtype 是 syntax-table。 subtype 是一个 symbol ,后面介绍 symbol的时候,我们会知道每一个 symbol 都有很多 property 。 一个有效 subtype ,必须有一个 property ,叫做 `char-table-extra-slots' ,是一个在 0 和 10 之间的一个 integer ,这个 integer 指 明了 char-table 有多少个 extra slot 可以使用。

例如:

  (get (char-table-subtype buffer-display-table) 'char-table-extra-slots)
   ; => 6, 有 6 个 extra slot
  (get (char-table-subtype (syntax-table)) 'char-table-extra-slots)
   ; => 0, 没有 extra slot

char-table 可以有 "parent" ,是另外一个 char-table 。如果一个 char-table 有 parent , 那么当索引一个 char-table 内的值如果是 nil ,那么就会在 char-table 的 parent 中查找。或者说 如果 CHAR-TABLE 在 C 的位置的值是 nil ,那么 `(aref CHAR-TABLE C) ' 就会 CHAR-TABLE 的 parent 中的值。

;; 创建一个 subtype
(put 'my-test-subtype 'char-table-extra-slots 1)
;; 如果 subtype 没有 char-table-extra-slots 的属性,那么会产
;; 生错误。 char-table 中的默认值是 100 ,也可以不指定默认值。
;; 不指定的时候,默认值是 nil
(setq a-char-table (make-char-table  'my-test-subtype 100))
;; 返回 100, 使用默认值。
(aref a-char-table ?A)
;; 设置新值
(aset a-char-table ?A 200)
;; 返回 200
(aref a-char-table ?A)
;; 返回 100
(aref a-char-table ?B)
;; 返回 t
(char-table-p a-char-table)
;;设置新的默认值
(set-char-table-default a-char-table ?A 1)
;; 返回 200
(aref a-char-table ?A)
;; 不指定数值
(aset a-char-table ?A nil)
;; 返回 1 ,刚刚设置过的默认值
(aref a-char-table ?A)
;; 返回 100, 其他的默认值还是 100
(aref a-char-table ?B)
;;
(setq another-char-table (make-char-table 'my-test-subtype))
;;返回 nil ,因为所有的默认值都是 nil
(aref another-char-table ?A)
;; 设置 another-char-table 的 parent 是 a-char-table
(set-char-table-parent another-char-table a-char-table)
;; 返回 a-char-table 中的 ?A 的值。
(aref another-char-table ?A)

(aset another-char-table ?A 53)
;; 返回 53
(aref another-char-table ?A)

(set-char-table-extra-slot a-char-table 0
                           '(haha Hello World))
;; 返回刚刚设置过的值 (haha Hello World)
(char-table-extra-slot a-char-table 0)

;; 返回一个 list ((491520 100) (458752 100) (442368 100)
;; (425984 100) (409600 100) (393216 100) (376832 100)
;; (360448 100) (344064 100) (327680 100) (311296 100)
;; (294912 100) ...)
(let (accumulator)
  (map-char-table
   #'(lambda (key value)
       (setq accumulator
             (cons (list key value) accumulator)))
   a-char-table)
  accumulator)
;; 返回 507904 , a-char-table 中元素的个数。
(length a-char-table)