types – 如何在sbcl(或常见的lisp)的vector中指定元素类型?
我尝试在sbcl 1.1.14中使用代码,但似乎类型检查忽略了vector元素的声明.
(defun test (vec) (declare (type (vector integer) vec)) (format nil "~a~&" (elt vec 0))) 任何提示?谢谢! 解决方法
首先请注意,将声明作为类型检查不是标准ANSI Common Lisp提供的.这是CMUCL引入的扩展. SBCL是CMUCL的后代.
Common Lisp类型系统适用于向量和数组的方式有点不同寻常. 元素类型. 正在使用元素类型创建数组.这意味着Lisp系统将创建一个可以存储该类型元素的数组.但Common Lisp并不要求每个元素类型都有专门的数组版本.如果数组的特定版本不可用,则元素类型将升级为下一个“较大”类型. 元素类型升级示例 CL-USER 14 > (upgraded-array-element-type '(unsigned-byte 1)) (UNSIGNED-BYTE 1) CL-USER 15 > (upgraded-array-element-type '(unsigned-byte 2)) (UNSIGNED-BYTE 2) 因此有针对(无符号字节1)和(无符号字节2)优化的阵列版本. CL-USER 16 > (upgraded-array-element-type '(unsigned-byte 3)) (UNSIGNED-BYTE 4) OOPS!没有为(无符号字节3)优化的数组.如果你请求这样一个数组,你会得到一个稍大的数组(无符号字节4). CL-USER 17 > (upgraded-array-element-type '(unsigned-byte 4)) (UNSIGNED-BYTE 4) CL-USER 18 > (upgraded-array-element-type '(unsigned-byte 5)) (UNSIGNED-BYTE 8) CL-USER 19 > (upgraded-array-element-type 'integer) T 上图显示整数没有特殊数组.你会得到一个通用数组. 你的守则 (defun test (vec) (declare (type (vector integer) vec)) (format nil "~a~&" (elt vec 0))) 所以你的声明真的意味着: 变量vec绑定到一个可以保持整数的向量. 这并不意味着: 变量vec绑定到仅保持整数的向量. CL-USER 21 > (typep '#(a "b" #c) '(vector integer)) T 以上在我的Lisp中返回true,因为向量是一般向量,它可以存储整数.因此它会检查向量的类型,但它并不关心向量的内容是否实际上都是整数类型.它只是说,向量COULD包含整数. 基于谓词的类型检查 Common Lisp允许类型声明使用谓词. CL-USER 28 > (defun vector-of-numbers-p (vector) (and (typep vector 'vector) (every 'integerp vector))) VECTOR-OF-NUMBERS-P CL-USER 29 > (typep '#(a "b" #c) '(satisfies arrayp)) T CL-USER 30 > (typep '#(a "b" #c) '(satisfies vector-of-numbers-p)) NIL CL-USER 31 > (typep '#(1 2 3) '(satisfies vector-of-numbers-p)) T 但是在编译时检查一下?可能不是. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |