3

如何正确指定可扩展向量的 common-lisp 类型(即,vector-push-extend 可接受),以便可以复制它。例如,如果一个向量定义为:

(defparameter v (make-array 2
                            :initial-contents '((a (b)) (c (d) e))
                            :adjustable t
                            :fill-pointer t))

我复制它的简单(不正确)方法是:

(map 'array #'copy-tree v)

但这会在 sbcl 中产生类型错误。正确的序列类型规范可以使这项工作吗?

4

2 回答 2

5

简单复制

你可以简单地这样做:

(map (type-of v) #'copy-tree v)

类型是什么?

CL-USER> (type-of v)
(VECTOR T 2)

以下内容就足够了:

(map 'vector #'copy-tree v)

该图有助于记住类型层次结构,尤其是数组和向量。

可调,填充指针,...

然而,得到的向量是不可调整的。也许这样的事情可以帮助:

(defun my-copy (vector)
  (map-into (make-array (array-dimensions vector)
                        :adjustable (adjustable-array-p vector)
                        :fill-pointer (fill-pointer vector))
            #'copy-tree
            vector))
于 2017-01-20T20:54:13.607 回答
3

MAP结果类型需要一个序列类型说明符ARRAY不是一个。SEQUENCEareVECTOR和的子类型的示例LIST

a 的类型声明语法VECTOR是:vector [{element-type | *} [{size | *}]].

无法在向量类型声明中指定诸如可调填充指针位移等特征。相应的功能选项也没有作为关键字提供给功能make-sequence。也copy-seq不会创建具有此类特征的向量。要创建这样的向量,您必须使用MAKE-ARRAY.

因此选项是:

  • 也许向量类型就足够了
  • 对于具有特殊功能的向量,通过创建它们MAKE-ARRAY并使用类似的功能MAP-INTO-> 请参阅 coredump 的出色答案。
于 2017-01-20T21:13:50.303 回答