Common Lisp 符号中文文档
Table of Contents
- 1. 函数/宏
- 1.1. +
- 1.2. -
- 1.3. *
- 1.4. /
- 1.5. 1+
- 1.6. 1-
- 1.7. and
- 1.8. atom
- 1.9. arrayp
- 1.10. aref
- 1.11. assoc
- 1.12. character
- 1.13. char-code
- 1.14. coerce
- 1.15. cons
- 1.16. decf
- 1.17. defmethod
- 1.18. defconstant
- 1.19. describe
- 1.20. do
- 1.21. dolist
- 1.22. dotimes
- 1.23. eq
- 1.24. eql
- 1.25. euqal
- 1.26. equalp
- 1.27. ensure-directories-exist
- 1.28. fboundp
- 1.29. found-symbol
- 1.30. force-output
- 1.31. incf
- 1.32. input-stream-p
- 1.33. list
- 1.34. listp
- 1.35. list-all-packages
- 1.36. loop
- 1.37. long-site-name
- 1.38. machine-type
- 1.39. machine-version
- 1.40. machine-instance
- 1.41. macroexpand
- 1.42. macroexpand-1
- 1.43. make-string
- 1.44. short-site-name
- 1.45. string-left-trim
- 1.46. string-right-trim
- 1.47. string-trim
- 1.48. software-type
- 1.49. software-version
- 1.50. shiftf
- 1.51. substitute
- 1.52. minusp
- 1.53. mismatch
- 1.54. multiple-value-prog1
- 1.55. null
- 1.56. numberp
- 1.57. notany
- 1.58. nth-value
- 1.59. nthcdr
- 1.60. output-stream-p
- 1.61. pairlis
- 1.62. plusp
- 1.63. progn
- 1.64. psetf
- 1.65. parse-integer
- 1.66. rename-file
- 1.67. rotatef
- 1.68. set
- 1.69. string-capitalize
- 1.70. svref
- 1.71. symbol-value
- 1.72. time
- 1.73. truncate
- 1.74. trace
- 1.75. type-of
- 1.76. unintern
- 1.77. unwind-protect
- 1.78. values
- 1.79. vector
- 1.80. with-standard-io-syntax
- 1.81. write-to-string
- 1.82. zerop
- 2. 全局常量/变量
1. 函数/宏
1.1. +
(+ &rest numbers)
加法。
(+ 1 1) ; => 2 (+ 1 2 3) ; => 6
1.2. -
(- number &rest more-numbers)
减法。
(- 2 1) ; => 1 ;;; 等同 10 - 8 - 1 (- 10 8 1) ; => 1 ;;; 如果只有一个数字,就取它的负数 (- 2) ; => -2
1.3. *
(* &rest numbers)
乘法。
(* 3 2 5) ; => 30
1.4. /
(/ number &rest more-numbers)
除法。
(/ 3) ; => 1/3 ;;; 无法整除时返回有理数 (/ 3 2) ; => 3/2 (/ 10 5) ; => 2
1.5. 1+
(1+ number)
返回 number 加 1 后的值。
(1+ 1.0) ; => 2.0 (1+ 10) ; => 11
1.6. 1-
(1- number)
返回 number 减 1 后的值。
(1- 10) ; => 9
1.7. and
(and &rest forms)
所有 form 计算如果都不为 nil,返回最后个 form 的值,否则返回 nil。
(and 1 2 3) ; => 3 (and 1 2 nil) ; => NIL
1.8. atom
(atom object)
谓词函数,判断 object 是否是一个原子,术语“原子”解释请见[这里](/cl/term)
(atom "123") ; => T (atom '1) ; => T (atom "1") ; => T (atom #\1) ; => T (atom 1) ; => T (atom nil) ; => T ;;; 非空列表不是原子 (atom '(1 2 3)) ; => NIL
1.9. arrayp
(arrayp object)
谓词函数,判断 object 是否是数组
(defvar x (make-array 10 :initial-element 1)) (arrayp x) ; => T
1.10. aref
(aref array &rest subscripts)
访问数组元素。参数 subscripts 是有效的下标,如果是多维数组,subscripts 应该有多个下标值,具体看示例。
;;; 访问一维数组中下标0和下标1的元素 (aref #(A B C) 0) ; => A (aref #(A B C) 1) ; => B ;;; 访问二维数组 (defvar a-rank-array (make-array '(2 2))) ; 创建一个二维数组 (aref a-rank-array 0 1) ; => 0 (setf (aref a-rank-array 0 1) 1) ; => 1 a-rank-array ; => #2A((0 1) (0 0)) ;;; 由于 aref 是直接指向数组元素的内存地址,所以借助它可修改数组元素: (defvar a-array #(1 2 3)) (setf (aref a-array 2) 'A) a-array ; => #(1 2 A)
1.11. assoc
(assoc item alist &key key test test-not)
访问一个 association list 结构,association list 结构每个元素都是一个嵌套列表。
(assoc 'a '((a 1) (b 2))) ; => (A 1) ;;; 指定 :test 参数 (assoc "a" '(("a" 1) ("b" 2)) :test #'equal) ; => ("a" 1)
1.12. character
(character obj)
返回对象的字符表示。
(character #\a) ; => #\a ;;; 字符串只能包含一个字符,包含多个字符会出错 (character "a") ; => #\a (character 'a) ; => #\A (character 100) ; 错误,不能是数字
注意,在 CLISP 实现里,如果参数为数字就返回对应的 ASCII 字符:
(character 97) ; => #\a (character 0) ; => #\Null
1.13. char-code
(char-code character)
返回字符对应的 ASCII 码。
(char-code #\a) ; => 97 (char-code #\A) ; => 65
1.14. coerce
(coerce ojb output-type)
转换 obj 的类型。
;;; 如果 obj 的类型和 output-type 一样的,就原样返回: (coerce 1 'integer) ; => 1 (coerce "1" 'string) ; => "1" ;;; 把 obj 转换成序列: (coerce "hello world" 'simple-vector) ; => #(#\h #\e #\l #\l #\o #\ #\w #\o #\r #\l #\d) (coerce "hello world" 'list) ; => (#\h #\e #\l #\l #\o #\ #\w #\o #\r #\l #\d) (coerce "hello world" 'array) ; => "hello world" ;;; 字符列表转成字符串: (coerce '(#\h #\e #\l #\l #\o) 'string) ; => "hello" ;;; 转换成字符: (coerce 'a 'character) ; => #\A (coerce 'hello 'character) ; 错误,obj 必须是单字符 (coerce :a 'character) ; => #\A ;;; 数字类型转换: ;; 转换成复数类型 (coerce 1.23 'complex) ; => #C(1.23 0.0)' ;; 转换成浮点数类型 (coerce 1 'float) ; => 1.0 ;;; 根据符号名转换成已绑定的函数。注意必须是函数,不能用在宏上: (coerce '+ 'function) ; => #<FUNCTION +> ;;; 调用返回的函数类型 (funcall (coerce '+ 'function) 1 1) ; => 2 (coerce "+" 'function) ; 错误,名字不能是字符串
1.15. cons
(cons se1 se2)
创建一个 cons cell。se1 是左指针,se2 是右指针。
;;; 左边指针指向存储了“1”的内存地址,右边指针指向存储了“2”的内存地址 (cons 1 2) ; => (1 . 2) (cons 1 nil) ; => (1) (cons 1 (cons 2 nil)) ; => (1 2)
1.16. decf
(decf place delta)
对 place 指向的内存位置做减法操作。delta 是减去的值,默认是1,也可以是一个表达式计算结果。
(defvar a-value 10) ;;; 默认减1 (decf a-value) ; => 9 ;;; 对象的值减2 (decf a-value (+ 1 1)) ; => 7
1.17. defmethod
(defmethod name &rest args)
定义方法,可以根据传入参数的类型动态调用。
(defmethod add ((a number) (b number)) (+ a b)) (defmethod add ((a list) (b list)) (append a b)) (add 1 1) ; => 2 (add '(1 2) '(3 4)) ; => (1 2 3 4)
1.18. defconstant
(defconstant name value &optional doc)
定义一个常量。Common Lisp 里常量名一般用“+”包围,最好是遵守这个命名约定。
(defconstant +a-constant+ 10) (defconstant +a-constant+ 10 "定义一个常量") +a-constant+ ; => 10
1.19. describe
(describe obj &optional output)
查看对象的信息。
;;; 查看 funcall 函数的信息 (describe 'funcall) ;; => ;; COMMON-LISP:FUNCALL ;; [symbol] ;; FUNCALL names a compiled function: ;; Lambda-list: (FUNCTION &REST ARGUMENTS) ;; Declared type: (FUNCTION ((OR FUNCTION SYMBOL) &REST T) *) ;; Documentation: ;; Call FUNCTION with the given ARGUMENTS. ;; Known attributes: call, unwind, any ;; Source file: SYS:SRC;CODE;EVAL.LISP
1.20. do
(do varlist endlist &body body)
循环。
参数 varlist 用来定义变量,可指定初始值以及步长:
(i) ; 定义变量 i (i 0) ; 定义变量 i,并初始为 0 (i 0 (+1 i)) ; 定义变量i并初始为 0,每次循环都会调用 +1 进行自加操作
endlist 指定循环结束的条件,以及返回值:
((> i 100)) ; 结束条件为 i 大于 100 ((> i 100) i) ; 指定 do 循环的返回值 i
例:从 1 加到 100,过程中打印 i 的值,最后表达式返回相加结果:
(do ((i 0 (1+ i)) ;; 变量n作为累加器 (n 0 (+ n i)) ) ((> i 100) n) (print i))
1.21. dolist
(dolist (var list &optional result) &body body)
迭代一个 list 对象。
- var:参数存储每次取到 list 元素的值。
- list:遍历的对象。
- result:可选参数,指定表达式。
(dolist (i '(1 2 3 4 5))
(print i))
1.22. dotimes
(dotimes (var count &optional result) &body body)
按次数循环。
(dotimes (i 100 i)
(print i))
1.23. eq
(eq obj1 obj2)
比较 obj1 和 obj2 是不是同个对象,或者指向同个对象,是则返回t,否则返回 nil。
(defvar hello "hello world") (defvar a hello) (defvar b hello) (eq a b) ; => T (defvar c a) (eq a c) ; => T (eq b c) ; => T c ; => "hello world" (defvar d "hi") (eq d c) ; => NIL (defvar a-list '(a b a)) (eq (car a-list) (caddr a-list)) ; => T
1.24. eql
(eql obj1 obj2)
判断 obj1 和 obj2 是否相等,规则:
1、(eq obj1 obj2) 为 t,那 eql 也返回 t。
2、obj1 和 obj2 是两个相同类型的数字,并且值也相等。
3、obj1 和 obj2 是两个相同的字符。
(defvar a 1) (defvar b a) ;;; 指向相同对象 (eqlf a b) ; => T ;;; 相同类型、相同值的数字 (eql 1 1) ; => T ;;; 类型不同,所以返回 nil (eql 1 1.0) ; => NIL ;;; 相同的字符 (eql #\a #\a) ; => T (defvar a-list '(1 2 3)) ;;; 值相同,但并不是一个对象,所以返回 nil (eql a-list '(1 2 3)) ; => NIL
1.25. euqal
(euqal x y)
判断 x 和 y 是否相等,比 eql 判断得更深入一些。
;;; 符号判断和 eq 的规则一样 (equal 'a 'a) ; => T ;;; 数字判断和 eql 规则一样 (equal 100 100) ; => T ;;; 字符判断和 eql 规则一样 (equal #\a #\a) ; => T ;;; 判断 cons ;; 元素相同也为 t (equal '(1 2 3) '(1 2 3)) ; => T ;; 元素顺序必须一致才返回 t (equal '(1 2 3) '(3 2 1)) ; => NIL ;;; 判断 array ;;; 只有字符串和 bit-vector 才能判断是否相等 (equal "test" "test") ; => T ;;; 字符串比较时不会忽略大小写 (equal "Test" "test") ; => NIL (equal #*1001 #*1001) ; => T ;;; 其他 array 无法比较 (equal #(1 2 3) #(1 2 3)) ; => NIL ;;; 判断 pathname 是否相等 (equal #p"/tmp/test" #p"/tmp/test") ; => T
1.26. equalp
(equalp x y)
比较两个对象是否相等。比 equal 判断得还要深入一些。
;;; 字符串比较会忽略大小写 (equalp "Test" "test") ; => T ;;; 比较 array 是否相等 (equalp #(1 2 3) #(1 2 3)) ; => T ;;; 字符比较 (equalp #\a #\a) ; => T ;;; 数字比较 (equalp 1 1) ; => T ;;; 整数和浮点数比较 (equalp 1 1.0) ; => T ;;; cons 比较 (equalp '(1 2 3) '(1 2 3)) ; => T ;;; 比较结构体 (make-my-info :name "lu4nx" :blog "shellcodes.org") ; => #S(MY-INFO :NAME "lu4nx" :BLOG "shellcodes.org") (defvar a (make-my-info :name "lu4nx" :blog "shellcodes.org")) (defvar b (make-my-info :name "lu4nx" :blog "shellcodes.org")) (equalp a b) ; => T ;;; 元素不相等返回 nil (equalp a (make-my-info :name "luanx" :blog "shellcodes.org")) ; => NIL ;;; 比较 hash 表 (defvar x (make-hash-table)) (defvar y (make-hash-table)) ;;; 两个 hash 表都是空元素,所以相等 (equalp x y) ; => T ;;; 给其中一个 hash 表设置键值后再比较 (setf (gethash :name x) "lu4nx") ; => "lu4nx" (equalp x y) ; => NIL
1.27. ensure-directories-exist
(ensure-directories-exist path &key verbose (mode 511))
创建一个目录。path 指定的路径一定要以“/”结尾。
(ensure-directories-exist "/tmp/test-function/") ;; => "/tmp/test-function/" ;; T ;;;; 如果路径不以“/”结尾,目录 a 是不会被创建的 (ensure-directories-exist "/tmp/test-function/a") ;; => "/tmp/test-function/a" ;; NIL
1.28. fboundp
(fboundp name)
判断符号是否绑定了函数。
(fboundp '+) ; => T (fboundp 'a) ; => NIL
1.29. found-symbol
(find name &optional package)
从指定包里查找符号,默认从 *package*
里查找。
(defvar hello "hello") ;; 字符串要大写 (find-symbol "HELLO") ; => HELLO ;; 从 CL 包里查找 funcall (find-symbol "FUNCALL" :cl) ; => FUNCALL ;; 直接调用返回的函数符号 (funcall (find-symbol "+" :cl) 1 1) ; => 2
1.30. force-output
(force-output &optional (stream *standard-output*
))
在 stream 指向的缓存取的内容为空时不等待。
下面这段代码在 SBCL 下执行时,只有输入了内容才会看到提示字符“say:”:
(format t "say:")
(read)
注:CLISP 会先打印字符串,再等待输入,等同默认加了 force-output 操作。
force-output 可以在等待输入之前就看到输出的字符串:
(format t "say:")
(force-output)
(read)
1.31. incf
(incf place delta-form)
对 delta-form 形式进行求值,并把求值结果加到 place 上,delta-form 默认为1。
注意:incf 是有副作用的,它直接修改 place 的值,而不是返回一个新值
(incf n) ; 等同于 (setf n (1+ n)) (incf n 10) ; 等同于 (setf n (+ n 10)) (defvar a 1) (incf a) ; => 2 a ; => 2 (incf a 10) ; => 12 (incf a (+ 1 1)) ; => 14 a ; => 14
1.32. input-stream-p
(input-stream-p stream)
判断 stream 是否是输入流对象。
(input-stream-p *standard-input*) ; => T (input-stream-p *standard-output*) ; => NIL
1.33. list
(list &rest args)
创建一个列表。
(list 1 2 3) ; => (1 2 3) (list 1 2 3 'a 'b 'c) ; => (1 2 3 A B C)
1.34. listp
(listp object)
谓词函数,判断 object 是否是 list 对象,是的话返回 t,否则返回 nil
(listp '(1 2 3)) ; => T (listp 123) ; => NIL
1.35. list-all-packages
(list-all-packages)
列出当前镜像中所有的包
1.36. loop
(loop &rest keywords-and-forms)
loop 宏较复杂,请在这里查看更多示例。
1.37. long-site-name
(long-site-name)
获得机器信息。不同的 Common Lisp 实现返回的信息不一致。
;; for CLISP (long-site-name) ; => "Linux mypc 4.3.5-300.fc23.x86_64 #1 SMP Mon Feb 1 03:18:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux" ;; for Allegro CL (long-site-name) ; => "MYPC" ;; for LispWorks (long-site-name) ; => "unknown" ;; for SBCL (long-site-name) ; => NIL
1.38. machine-type
(machine-type)
获得处理器架构信息。
(machine-type) ; => "X86-64"
1.39. machine-version
(machine-version)
获得处理器信息。
(machine-version) ; => "Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz"
1.40. machine-instance
(machine-instance)
获得 Common Lisp 运行的平台信息,不同的实现返回的结果不一样,比如 SBCL 返回主机名:
(machine-instance) ; => "mypc"
1.41. macroexpand
(macroexpand form &optional env)
展开全部的宏。
(macroexpand '(dotimes (i 10) (print i))) ;; 展开后: ;; (BLOCK NIL ;; (LET ((I 0)) ;; (DECLARE (TYPE UNSIGNED-BYTE I)) ;; (TAGBODY ;; (GO #:G682) ;; #:G681 ;; (TAGBODY (PRINT I)) ;; (PSETQ I (1+ I)) ;; #:G682 ;; (UNLESS (>= I 10) (GO #:G681)) ;; (RETURN-FROM NIL (PROGN NIL))))) ;; T
1.42. macroexpand-1
(macroexpand-1 form &optional env)
展开宏表达式。macroexpand-1 只展开一层宏,而不是全部展开。
(macroexpand-1 '(dotimes (i 10) (print i))) ;; 展开后: ;; (DO ((I 0 (1+ I))) ((>= I 10) NIL) (DECLARE (TYPE UNSIGNED-BYTE I)) (PRINT I)) ;; T
也可以把 macroexpand-1 用作判断表达式是否是宏,如果是宏就返回 t,否则返回 nil:
1.43. make-string
(make-string count &key (element-type 'character) initial-element)
返回包含重复了 count 次的参数 initial-element 的字符串。
(make-string 10 :initial-element #\a) ; => "aaaaaaaaaa"
注意:如果 initial-element 不指定值,各个 Common Lisp 实现对返回的结果是不一样的。
1.44. short-site-name
(short-site-name)
获得机器信息。不同的 Common Lisp 实现返回的信息不一致。
;; for CLISP,返回主机名 (short-site-name) ; => "lx" ;; for Allegro CL (short-site-name) ; => "LU4NX-PC" ;; for LispWorks (short-site-name) ; => "Unknown" ;; for SBCL (short-site-name) ; => NIL
1.45. string-left-trim
(string-left-trim char-bag string)
从 string 左边开始将 char-bag 指定的内容剔除掉,如果 string 的起始内容和 char-bag 不一样,就原样返回,否则返回一个新的字符串。
;;; 只会剔除第一次匹配到的 (string-left-trim "Hi" "Hi,girl. Hi,boy.") ; => ",girl. Hi,boy."
1.46. string-right-trim
(string-right-trim char-bag string)
同 string-left-trim 一样,只是方向是从右边。
(string-right-trim "boy." "Hi,girl. Hi,boy.") ; => "Hi,girl. Hi,"
1.47. string-trim
(string-trim char-bag string)
从 string 左边或右边开始将 char-bag 指定的内容剔除掉。
(string-trim "hello" "hello, world") ; => ", world" (string-trim "world" "hello, world") ; => "hello, "
1.48. software-type
(software-type)
返回操作系统平台信息,SBCL 输出:
(software-type) ; => "Linux"
1.49. software-version
(software-version)
返回平台的版本号,SBCL 输出:
(software-version) ; => "4.3.5-300.fc23.x86_64"
1.50. shiftf
(shiftf &rest args)
从右向左重新赋值:将最后一个表达式的值赋值给倒数第二个的 place,倒数第二个 place 的值赋值给倒数第三个 place,依次类推。
(defvar a 1) (defvar b 2) (defvar c 3) (shiftf a b c 4) ; => 1 a ; => 2 b ; => 3 c ; => 4 ;;;; 第二个例子:修改列表 (defvar x '(a b c)) (defvar y 'd) (defvar z 0) (shiftf z (nth 1 x) y) ; => 0 z ; => B x ; => (A D Z) y ; => D
1.51. substitute
(substitute new old seq &rest args &key from-end (test #'eql) test-not (start 0) count end key)
替换序列中的内容。
(substitute #\a #\b "abcd") ; => "aacd" (substitute 10 1 #(1 2 3 4 5)) ; => #(10 2 3 4 5)
1.52. minusp
(minusp number)
如果number小于0,返回T
(minusp 1) ; => NIL (minusp 0) ; => NIL (minusp -1) ; => T
1.53. mismatch
(mismatch seq1 seq2 &rest args &key from-end (test '#eql) test-not (start1 0) end1 (start2 0) end2 key)
返回两个向量首次不同的位置。
(mismatch "http://www.shellcodes.org" "http://") ; => 7
1.54. multiple-value-prog1
(multiple-value-prog1 values-form &rest forms)
执行多个表达式,并把第一个表达式的执行结果作为返回结果。
(multiple-value-prog1 (1+ 1) (print "a") (print "b")) ;; 输出: ;; "a" ;; "b" ;; 2
1.55. null
(null object)
判断 object 是否为 nil
(null nil) ; => T ;;; 空列表等同于 nil (null '()) ; => T (null 1) ; => NIL
1.56. numberp
(numberp object)
谓词函数,判断 object 是否是 number,是的话返回 t,否则返回 nil
(numberp 123) ; => T (numberp 123.0) ; => T (numberp 0.1) ; => T (numberp "1") ; => NIL (numberp 1/2) ; => T
1.57. notany
(notany pred seq1 &rest more-seqs)
参数 pred 是一个谓词函数,提供一个或多个序列用作判断,如果全部不为真,notany 返回 T。
如果只提供一个序列,那么序列中的每个元素会被应用到函数上:
(notany #'evenp '(1 2 3 4)) ; => NIL (notany #'evenp '(1 3 5 7)) ; => T
如果提供多个序列,会同时传递多个参数给函数,所以函数需要支持指定参数数量才行:
(notany #'equal '(1 3 5 7) '(1 3 5 7)) ; => NIL ;;; 全部不相等 (notany #'equal '(1 3 5 7) '(2 4 6 8)) ; => T
1.58. nth-value
(nth-value n form)
form 是一个返回多值的表达式,参数 n 用来指定获得哪一个值,n 从 0 开始计数。
(nth-value 1 (values 'value1 "value2")) ; => "value2" (nth-value 0 (values 'value1 "value2")) ; => VALUE1
1.59. nthcdr
(nthcdr n list)
对 list 指定 n 次“cdr“。
;;; 等同于 (cdr (cdr '(1 2 3))) (nthcdr 2 '(1 2 3)) ; => (3)
1.60. output-stream-p
(output-stream-p stream)
判断 stream 是否是一个可输出的流对象,是则返回 t,否则返回 nil。
(output-stream-p *standard-input*) ; => NIL (output-stream-p *standard-output*) ; => T
1.61. pairlis
(pairlis keys data &optional alist)
构造 alist。
(pairlis '(a b c) '(1 2 3)) ; => ((C . 3) (B . 2) (A . 1)) ;;; 指定最后一个 alist 参数 (pairlis '(a b c) '(1 2 3) '((x 1) (y 2) (z 3))) ; => ((C . 3) (B . 2) (A . 1) (X 1) (Y 2) (Z 3))
1.62. plusp
(plusp number)
如果 number 大于 0,返回 T:
(plusp 1) ; => T (plusp 0) ; => NIL (plusp -1) ; => NIL
1.63. progn
(progn &rest forms)
执行多个表达式,并将表达式最后个值作为返回值。
Q:什么时候该用 progn,什么时候用 block?
A:如果需要突然退出,使用 block,其他时候则用 progn。
(progn (print 1) (print 2) 3) ;; 输出: ;; 1 ;; 2 ;; 3
1.64. psetf
(psetf &rest pairs)
给多个 pair 分配新的值。
(defvar x '(1 2 3)) (defvar y '(4 5 6)) (psetf (car x) 'one (car y) 'four) ; => NIL x ; => (ONE 2 3) y ; => (FOUR 5 6) (psetf x 1 y 2) ; => NIL x ; => 1 y ; => 2
1.65. parse-integer
(parse-integer string &key (start 0) end (radix 10) junk-allowed)
将字符串转换成数字。这个函数会返回两个值,第一个值是转换结果,第二个值是转换的字符数。
(parse-integer "123") ; => 123 ; 3 ;;; radix 指定进制,这里转换二进制 (parse-integer "1101" :radix 2) ; => 13 ; 4
1.66. rename-file
(rename-file file new-name)
重命名文件
(rename-file #p"/tmp/old" "new")
1.67. rotatef
(rotatef &rest args)
旋转式交换变量的值
注意:rotatef 有副作用,是直接修改符号的值
(defvar a 1) (defvar b 2) (defvar c 3) a ; => 1 b ; => 2 c ; => 3 (rotatef a b c) ; => NIL a ; => 2 b ; => 3 ;;; 因为是轮旋交换变量,c 是最后个变量,所以应该取第一个变量的值 c ; => 1
技巧 1:交换两个变量的值:
(defvar var1 1) (defvar var2 2) (rotatef var1 var2) var1 ; => 2 var2 ; => 1
技巧2:交换列表中的值:
(defvar a-list '(a 1 b 2 c 3)) (rotatef (nth 0 a-list) (nth 1 a-list)) ; => NIL a-list ; => (1 A B 2 C 3)
1.68. set
(set symbol value)
改变 symbol 的值。symbol 必须加单引号(用 setq 可以省略单引号)。
(set 'a 1) ; => 1 a ; => 1
1.69. string-capitalize
(string-capitalize stirng &key (start 0) end)
将字符串中英文单词首字母大写。
(string-capitalize "hello world") ; => "Hello World"
1.70. svref
(svref vector index)
svref 用来快速索引向量(vector)。
(svref #(1 2 3 4 5 6) 3) ; => 4
1.71. symbol-value
(symbol-value symbol)
返回符号对应的值。
(defvar hi "hi") (symbol-value 'hi) ; => "hi"
1.72. time
(time form)
测试一个表达式执行需要花费多长时间。
(time (sleep 10)) ;; Evaluation took: ;; 10.0000 seconds of real time ;; 0.012742 seconds of total run time (0.009542 user, 0.003200 system) ;; 0.13% CPU ;; 28,934,402,420 processor cycles ;; 68,336 bytes consed
1.73. truncate
(truncate number &optional divisor)
返回浮点数整数和小数部分。参数 divisor 是除数,默认为 1。
(truncate pi) ;; 输出: ;; 3 ;; 0.14159265358979312d0 (truncate pi 3) ;; 输出: ;; 1 ;; 0.14159265358979312d0
1.74. trace
(trace &rest specs)
跟踪函数调用。
比如定义一个斐波那契数列:
(defun fab (n) (cond ((equal 0 n) 0) ((equal 1 n) 1) (t (+ (fab (- n 1)) (fab (- n 2))))))
然后对 fab 函数进行调用跟踪:
(trace fab)
调用 trace 函数后再执行它,就可以看到函数调用过程:
(fab 5) ;; 输出: ;; 0: (FAB 5) ;; 1: (FAB 4) ;; 2: (FAB 3) ;; 3: (FAB 2) ;; 4: (FAB 1) ;; 4: FAB returned 1 ;; 4: (FAB 0) ;; 4: FAB returned 0 ;; 3: FAB returned 1 ;; 3: (FAB 1) ;; 3: FAB returned 1 ;; 2: FAB returned 2 ;; 2: (FAB 2) ;; 3: (FAB 1) ;; 3: FAB returned 1 ;; 3: (FAB 0) ;; 3: FAB returned 0 ;; 2: FAB returned 1 ;; 1: FAB returned 3 ;; 1: (FAB 3) ;; 2: (FAB 2) ;; 3: (FAB 1) ;; 3: FAB returned 1 ;; 3: (FAB 0) ;; 3: FAB returned 0 ;; 2: FAB returned 1 ;; 2: (FAB 1) ;; 2: FAB returned 1 ;; 1: FAB returned 2 ;; 0: FAB returned 5 ;; 5
trace 函数如果不跟参数,列出当前被 trace 过的函数:
(trace) ; => (FAB)
用 untrace 函数可以解除跟踪。
1.75. type-of
(type-of object)
查看对象的类型
(type-of 1) ; => BIT (type-of 12345) ; => (INTEGER 0 4611686018427387903) (type-of "abc") ; => (SIMPLE-ARRAY CHARACTER (3)) (type-of #\a) ; => nSTANDARD-CHAR (type-of '(1 2 3)) ; => CONS
1.76. unintern
(unintern symbol &optional package)
将一个符号从包中移除。
(defvar a 1) a ; => 2 (unintern 'a) ; => T a ; The variable A is unbound.
1.77. unwind-protect
(unwind-protect protected &body cleanup)
可以为表达式提供一个“清理函数”,保证无论发生什么异常都会去执行。如:
(defun hello () (unwind-protect (error "hello") ;; 一定在最后会被执行 (print "exit")))
Common Lisp 中常见的 with- 开头的宏基本上都是封装了 unwind-protect 的,比如我们展开 with-open-file 看看:
(macroexpand '(with-open-file (f "/etc/passwd"))) ;; 展开如下: (LET ((F (OPEN "/etc/passwd")) (#:G930 T)) (UNWIND-PROTECT (MULTIPLE-VALUE-PROG1 (PROGN) (SETQ #:G930 NIL)) (WHEN F (CLOSE F :ABORT #:G930)))) T
1.78. values
(values &rest values)
返回多个值。
(values 'value1 'value2) ;; 输出: ;; VALUE1 ;; VALUE2
1.79. vector
(vector &rest objs)
创建一个向量。
(vector 1 2 3) ; => #(1 2 3) (vector 1 2 3 'a 'b 'c) ; => #(1 2 3 A B C) ;;; #(...) 语法和 vector 函数等同: #(1 2 3) ; => #(1 2 3)
1.80. with-standard-io-syntax
(with-standard-io-syntax &body body)
在执行 body 的表示式时,将一些会影响 I/O 输出的变量恢复成默认值,防止动态绑定的影响。
(let ((a '(1 2 3 4 5)) ;; *print-length* 设置打印 list 时显示的元素数量 (*print-length* 3)) (print a) ; => (1 2 3 ...) (with-standard-io-syntax ;; 输出:(1 2 3 4 5),在 with-standard-io-syntax 代码块中,*print-length* 将恢复成默认值 (print a)))
1.81. write-to-string
(write-to-string obj)
返回对象的字符打印形式。
(write-to-string '(1 2 3)) ; => "(1 2 3)" ;; 可以作为数字和字符串的转换 (write-to-string 123) ; => "123" (write-to-string (make-hash-table)) ; => "#<HASH-TABLE :TEST EQL :COUNT 0 {10035DC8B3}>" (write-to-string #'and) ; => "#<CLOSURE (:MACRO AND) {1000BDFB8B}>" (write-to-string #(1 2 3)) ; => "#(1 2 3)"
1.82. zerop
(zerop number)
谓词函数,如果 number 等于 0,返回 T
(zerop 0) ; => T (zerop 1) ; => NIL
2. 全局常量/变量
2.1. 常量
常量 | 用途 |
---|---|
pi | 具体的精度取决于 Common Lisp 实现。 |
most-negative-fixnum | fixnum 类型允许的最小值。 |
most-positive-fixnum | fixnum 类型允许的最大值。 |
2.2. 变量
2.2.1. *print-array*
如果值为 t,打印数组时会打印具体内容,否则只打印数组信息。
(setf *print-array* nil) ; => NIL (print #(1 2 3)) ;; 输出: ;; #<(SIMPLE-VECTOR 3) {10031B641F}> ;; #<(SIMPLE-VECTOR 3) {10031B641F}> (setf *print-array* t) ; => T (print #(1 2 3)) ;; 输出: ;; #(1 2 3) ;; #(1 2 3)