为何Common Lisp的boolean-vector类型定义未生效?如何正确定义?
问题:布尔类型简单数组的类型定义未按预期工作
我尝试定义一个仅包含布尔元素的简单数组类型,编写了如下deftype代码:
(deftype boolean-vector (&optional (length '*)) "Simple vector of BOOLEAN elements." `(simple-array boolean (,length)))
但测试结果不符合预期:
CL-USER> (typep #(nil nil t t t) 'boolean-vector) T CL-USER> (typep #(nil nil t t 5) 'boolean-vector) T CL-USER> (typep 5 'boolean) NIL
明明5不是布尔类型,但包含5的数组却被判定为boolean-vector类型,请问这是为什么?该如何正确定义仅包含布尔元素的向量类型?
原因分析
在Common Lisp中,simple-array的元素类型参数(此处的boolean)仅表示数组的声明元素类型,用于存储优化,而非运行时强制检查每个元素的实际类型。typep检查数组类型时,只会验证数组是否为指定维度的简单数组,以及其声明元素类型是否兼容boolean,不会遍历检查每个元素的实际类型。因此即便数组中混入非布尔元素,只要数组本身是符合维度的简单数组,就会返回T。
正确解决方案
通过结合simple-array类型约束与satisfies子句,实现对每个元素的类型检查:
(defun boolean? (object) "检查OBJECT是否为BOOLEAN类型。" (typep object 'boolean)) (defun boolean-sequence-p (x) (every #'boolean? x)) (deftype simple-boolean-vector (&optional (length '*)) "仅包含BOOLEAN元素的简单向量类型。" `(and (simple-array * (,length)) (satisfies boolean-sequence-p)))
说明
boolean?函数用于检查单个对象是否为布尔类型;boolean-sequence-p函数通过every遍历序列,确保所有元素都满足布尔类型要求;simple-boolean-vector类型先约束数组为指定长度的简单数组,再通过satisfies调用boolean-sequence-p完成元素类型的全量检查。
内容的提问来源于stack exchange,提问作者CL-USER
相关产品推荐
相关产品推荐

