Emacs: Elisp 手册学习手稿
- TAG: 编码
使用 lisp 模式 M-x lisp-interaction-mode 或 Ielm 模式 M-x inferior-emacs-lisp-mode
Lisp 数据类型
(message "%s" emacs-build-time) "(26937 51891 419712 0)" (message "%s" emacs-version) "30.2" (message "%s" emacs-major-version) "30" (message "%s" emacs-minor-version) "2" (prin1 emacs-repository-version) nilnil (current-buffer) #<buffer *scratch*> (let ((a (list 1))) (setcdr a a)) (1 . #0) (setq a (list 1)) (1) (cdr a) nil () ;;; 编程类型 ;;;; 整数类型 (fixnump 1) t (bignump 1) nil (princ most-negative-fixnum) -2305843009213693952-2305843009213693952 (prin1 most-positive-fixnum) 23058430092136939512305843009213693951 (> most-positive-fixnum 99999) t -1 -1 1 1 1. 1 +1 1 ;;;; 浮点类型 ;; 浮点数看作一个分数与一个 10 的幂的组合 1500.0 +15e2 15.0e+2 +1500000e-3 ;;;; 字符类型 ?A 65 ?B 66 ?a 97 ?\( 40 ?\\ 92 ?\a ; C-g 7 ?\b ; DEL 8 ?\t ?\n ?\s ; 空格符 32 ?\ ; 多加一个空格,以便与后续文本分隔 32 ?\r 13 ?\+ ; 等价 ?+ ; 没有特殊转义含义的字符前面加反斜杠是允许的 ;; ()[]\;" 前必须加反斜杠。 |'`#., 前建议加 ?\| 124 ?| 124 ?\` 96 ;; 非 ASCII ?\N{LATIN SMALL LETTER A WITH GRAVE} ; 非 ASCII,如有名称。名称中的空格可以替换为任意非空空白序列(如换行) 224 ?à 224 ?\N{U+E0} 224 ?\u00e0 224 ?\U000000e0 224 ?\340 ; 八进制 224 ?\101 ; A 65 ?\001 ; C-a ;; 控制字符 ?\^I ; C-i 9 ?\^i ; C-i 9 ?\C-i ; C-i 9 ?\C-b ; C-b 2 ELISP> ?\^? ; DEL 字符视为 ? 127 (#o177, #x7f, ?\C-?) ELISP> ?\C-? 127 (#o177, #x7f, ?\C-?) ;; META 字符语法 ?\M-A ; meta 在高位 134217793 ELISP> ?\M-\101 134217793 (#o1000000101, #x8000041) ELISP> ?A 65 (#o101, #x41, ?A) ELISP> ?\M-\C-b ; C-M-b 134217730 (#o1000000002, #x8000002) ELISP> ?\C-\M-b 134217730 (#o1000000002, #x8000002) ELISP> ?\M-\002 134217730 (#o1000000002, #x8000002) ELISP> ?\C-b 2 (#o2, #x2, ?\C-b ;; 其他字符修饰符 ?\C-\S-o ; Shift-Ctrl-o 33554447 ?\S-\C-o 33554447 ;; hyper \H- ; super \s- ; alt \A- ?\H-\M-\A-x ; Alt-Hyper-Meta-x 155189368 ;;;; 符号类型 1+ ; 符号名称为 ‘1+’ ; (而非 ‘+1’ — 后者是整数)。 \+1 ; 符号名称为 ‘+1’ ; (可读性较差)。 \(*\ 1\ 2\) ; 符号名称为 ‘(* 1 2)’ (更差的名称)。 ;;;; 序列类型 ;; list ;; array: string, vector, char-table, bool-vector (length "aa") 2 (length '(aa)) 1 (length ["aa" "bb"]) 2 ;; 一般,不可能两次读取到同一序列对象;空列表除外,() === nill ;;;; Cons 单元与列表类型 ;; cons cell:是包含两个存储位的对象,分别称为 CAR 位和 CDR 位 ;; list:是由一系列 Cons 单元串联而成的结构:每个 Cons 单元的 cdr 位, ;; 要么存放着下一个 Cons 单元,要么存放着空列表。 ;; atoms:不是 Cons 单元的对象 ;; list (A 2 "A") () nil ("A ()") ((A B C)) ; 只有一个元素的列表 ;; CAR 与 CDR 这两个名称来源于 Lisp 历史。 ;; 最早的 Lisp 运行在 IBM 704 计算机上,该机将字分为地址部分(address)和减量部分(decrement); ;; CAR 是提取寄存器地址部分内容的指令,CDR 是提取寄存器减量部分内容的指令。 ;; 三元素列表 (rose violet buttercup) 等价于 (rose . (violet . (buttercup))) --- --- --- --- --- --- | | |--> | | |--> | | |--> nil --- --- --- --- --- --- | | | | | | --> rose --> violet --> buttercup ;; 关联列表类型 alist ;; 它的元素都是 cons 单元 (setq alist-of-colors '((rose . red) (lily . white) (buttercup . yellow))) ((rose . red) (lily . white) (buttercup . yellow)) ;; 这个变量是一个包含三个元素的关联列表。在第一个元素中,rose 是键,red 是值。 ;;;; 数组类型 ;; 四种数组:strings字符串、vectors向量、bool-vectors布尔向量和 char-tables字符表。 ;; 布尔向量只能存放 t 或 nil。 ;; 所有 Emacs Lisp 数组都是一维的。 ;;;; 字符串类型 ;; 字符串的读取语法是一对双引号,中间包含任意数量的字符 "\"" "foo\r" "foo\^Ibar" "foo bar" "\N{LATIN SMALL LETTER A WITH GRAVE}" "à" "\u00e0" "à" ;; 转义换行符,lisp 在读取字符串时会忽略转义换;转义空格同样会被忽略 "ab\ cd\ e" "abcde" ;; 字符串中的非 ASCII 字符 "\xe0" "\340" ;; 字符串中的不可打印字符 "\t, \C-a" " , " "\M-A" "\301" ;; 字符串中的文本属性 ;; #("characters" property-data...) 属性数据由零个或多个元素组成,每三个为一组 #("foo bar" 0 3 (face bold) 3 4 nil 4 7 (face italic)) ;; ‘foo bar’ 的字符串,其中:前三个字符拥有 face 属性,值为 bold(粗体);最后三个字符拥有 face 属性,值为 italic(斜体)。(第四个字符没有任何文本属性)。 ;;;; 向量类型 [1 "two" (three)] ; 包含三个元素的向量 ;;;; 字符表类型 ;; 字符表 = 用字符当下标的数组 ;; 打印长这样:#^[...] ;; 用途:给每个字符绑定信息(大小写、语法、显示、分类等) (setq my-char-table (make-char-table 'foo "默认值")) ; 创建一个空字符表 (aset my-char-table ?a 'letter-a) ; 给字符 'a' 赋值 (aref my-char-table ?a) ; 取 'a' 的值 letter-a ;;;; 布尔向量类型 ;; 布尔向量 是一种一维数组,其元素只能是 t(真)或 nil(假)。 ;; 打印表示形式与字符串类似,但开头会以 ‘#&’ 后跟长度值 (make-bool-vector 3 t) (make-bool-vector 3 nil) ELISP> ?\C-g 7 (#o7, #x7, ?\C-g) ELISP> ?\C-@ 0 (#o0, #x0, ?\C-@) ;; 布尔向量的长度不是 8 的整数倍, ;; 其打印表示会显示额外的元素,但这些额外元素实际上无任何意义。 (equal #&3"\377" #&3"\007") ; t ;;;; 哈希表类型 (make-hash-table) #s(hash-table) ;;;; 函数类型 (setq f 'list) list (funcall f 'x 'y 'z) ; 获取一个函数对象,然后使用原始函数 funcall 和 apply 来调用 (x y z) (apply '+ 1 2 '(3 4)) ; 其行为与 funcall 基本一致,但最后一项需为一个对象列表 10 ;;;; 宏类型 ;; 生成另一段 Lisp 表达式 (defmacro inc2 (var1 var2) (list 'progn (list 'inc var1) (list 'inc var2))) inc2 (macroexpand '(inc2 r s)) (progn (inc r) (inc s)) ;;;; 原语函数类型 ;; 子程序、内置函数,打印时#<xxx> (symbol-function 'car) ; 获取符号绑定的函数 #<subr car> (subrp (symbol-function 'car)) ; subrp 是否为原始函数 t ;;;; 闭包类型 ;; 是将函数定义转化为函数值时生成的函数对象 ;;;; 记录类型 ;; 作用创建不属于 Emacs 内置类型的自定义类型对象 ;;;; 类型描述符 ;; 用于存放类型相关信息的记录。 ;;;; 类型说明符 ;; 是表示一种类型的表达式。为函数接口提供文档等。 ;; 类型说明符可分为基本类型与复合类型。 (and 1 2) ; 只要其中一个生成nil,则返回nil。否则返回最后一个参数值。 2 (and 1 nil) nil (and nil 1) nil (or 1 2) ; 只要其中一个生成true,则返回true 内容。否则返回最后一个参数值。 1 (or nil 2) 2 (integer -10 10) ;;;; 自动加载类型 autoload (defun doctor ()xxxx) ;;;; 终结器类型 ;; 当返回的终结器对象在垃圾回收后变为不可达时,Emacs 就会调用与该终结器关联的函数。 ;;; 编辑类型