You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Common Lisp/SBCL中指定&rest参数的类型?

解决方案

方法一:显式检查每个参数(兼容性最好)

在函数内部使用check-type宏逐个验证&rest参数中的元素类型,这种方式在所有Common Lisp实现中都有效,且错误提示清晰符合需求:

(deftype fruit () '(member :apple :orange :pear))

(defun place-order (&rest selections)
  (dolist (s selections)
    (check-type s fruit) ; 显式检查每个元素的类型
    (format t "Ordering ~S~%" s)))

(place-order :orange :apple :bacon)

调用后会触发如下错误:

Unhandled TYPE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
                                  {1001DD0003}>:
  The value
    :BACON
  is not of type
    (MEMBER :APPLE :ORANGE :PEAR)
  when checking the type of S.

方法二:利用SBCL的类型扩展实现编译/运行时检查

SBCL支持proper-list扩展类型,可用来表示所有元素均为指定类型的真列表。结合高安全级别的优化声明,能让编译器在编译期(针对常量参数)或运行期(针对变量参数)进行类型检查:

(deftype fruit () '(member :apple :orange :pear))

; 开启最高安全级别,确保类型检查生效
(declaim (optimize (safety 3)))
; 声明&rest参数为所有元素都是fruit的真列表
(declaim (ftype (function (&rest (proper-list fruit))) place-order))

(defun place-order (&rest selections)
  (dolist (s selections)
    (format t "Ordering ~S~%" s)))

(place-order :orange :apple :bacon)

如果调用时传入的是常量参数,SBCL会在编译阶段直接报错;如果是变量参数,则会在运行时触发类型错误。


内容的提问来源于stack exchange,提问作者Dan Passaro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:55:20