如何在Common Lisp中正确声明list类型的类型说明符?
Common Lisp 中 list 类型说明符的声明方式按使用场景分为几类,和你提到的数组声明语法有一定差异:
1. 通用无限制列表声明
如果不需要限制列表的元素类型、长度,直接使用基础的 list 类型说明符即可,所有兼容 ANSI CL 标准的实现都支持:
(defun process-list (input-list) (declare (type list input-list)) ;; 函数逻辑 )
2. 定长异质列表声明
如果要声明固定长度、每个位置元素类型确定的列表,可以使用 (list 位置1类型 位置2类型 ...) 的复合类型说明符,这是 ANSI CL 标准定义的合法写法,类似数组声明里指定维度的效果:
;; 声明返回值是两元素列表,第一个为 fixnum 类型,第二个为 string 类型 (defun get-user () (declare (values (list fixnum string))) (list 1001 "李四"))
3. 任意长度同构列表声明
ANSI CL 标准没有为「所有元素类型相同、长度不固定的列表」这类场景提供原生的 list 复合语法,有两种常用实现方案:
- 标准兼容方案:自定义类型谓词,配合
satisfies类型说明符使用,兼容性最好但类型检查效率较低:
;; 自定义全fixnum列表的检查谓词 (defun fixnum-list-p (obj) (and (listp obj) (every #'fixnump obj))) ;; 声明变量类型 (defun sum-fixnums (num-list) (declare (type (satisfies fixnum-list-p) num-list)) (reduce #'+ num-list))
- 实现扩展方案:主流生产级 Common Lisp 实现都提供了专属的简化语法,类型检查效率和对编译器推导的支持都更好,比如 SBCL 可以直接写
sb-int:list-of,Clozure CL 可以用ccl:list-of:
;; SBCL 环境下的写法,声明为元素全是 fixnum 的任意长度列表 (defun sum-fixnums (num-list) (declare (type (sb-int:list-of fixnum) num-list)) (reduce #'+ num-list))
补充注意
list 类型默认包含空表 nil,如果你要声明的是非空列表,可以把类型写为 (cons t list),再按需叠加元素类型限制即可。
内容的提问来源于stack exchange,提问作者ccQpein
相关产品推荐
相关产品推荐

