加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

types – 如何在sbcl(或常见的lisp)的vector中指定元素类型?

发布时间:2020-12-15 04:41:55 所属栏目:Java 来源:网络整理
导读:我尝试在sbcl 1.1.14中使用代码,但似乎类型检查忽略了vector元素的声明. (defun test (vec) (declare (type (vector integer) vec)) (format nil "~a~" (elt vec 0))) 任何提示?谢谢! 解决方法 首先请注意,将声明作为类型检查不是标准ANSI Common Lisp提供
我尝试在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

但是在编译时检查一下?可能不是.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读