Common lisp运行时检查变量类型
在Common lisp里,可以采用如下几种方式在运行的时候检查变量类型。
Table of Contents
1 CHECK-TYPE
Macro CHECK-TYPE ;; 语法: check-type place typespec [string] => nil ;; 作用: 检查第一个参数的类型是否是第二个参数所指定的类型。 ;; 示例: CL-USER> (defun my-sqrt (x) (check-type x (real 0)) (sqrt x)) MY-SQRT CL-USER> (my-sqrt 9) 3.0 CL-USER> (my-sqrt -9) Type a form to be evaluated: 4 2.0 CL-USER> (check-type 9 (real 0)) ; in: CHECK-TYPE 9 ; (SETF 9 (SB-KERNEL:CHECK-TYPE-ERROR '9 #:G599 '(REAL 0))) ; ==> ; (SETQ 9 (SB-KERNEL:CHECK-TYPE-ERROR '9 #:G599 '(REAL 0))) ; ; caught ERROR: ; Variable name is not a symbol: 9. ; ; compilation unit finished ; caught 1 ERROR condition NIL ;; 注意点: a. 第一个参数会被求值,第二个参数不会被求值 b. 第一个参数不能只是普通的变量,其应当可以被setf设置 c. 如果第一个参数的类型不满足第二个参数指定的类型,那么会产生一个 TYPE-ERROR d. 产生 TYPE-ERROR 后提供一个restart选项,可以提供一个其他值作为第一个参数 e. check-type 的第三个参数是优化产生error后的提示信息
2 TYPEP
Function TYPEP ;; 语法: typep object type-specifier &optional environment => generalized-boolean ;; 作用: 检查object是否有type-specifier的类型 ;; 注意点: a. 不像check-type,typep是个函数,两个参数都会被求值,所以第二个类型参数需要quote传入 b. check-type不满足类型会产生error, typep会返还nil c. typep的第一个检查的参数不像check-type那样有限制
3 TYPE-OF
Function TYPE-OF ;; 语法: type-of object => typespec ;; 作用: 返回object的类型 ;;注意: 不同lisp实现之间的返回值可能不一致,如果追求可移植性,不建议使用
4 其它
;; 1. 在一些lisp实现比如sbcl里,可以采用 declare 等来确保变量类型, 如下 (defun my-sqrt (x) (declare (type (real 0) x)) (sqrt x)) 如果x为负数,那么会触发一个error,但没有restart选项。 但declare的可移植性是没法保证的。 ;; 2. typecase等,留待以后探究