区分整数和字符串向量

Distinguishing an integer from a string vector

我正在尝试根据数组类型进行分派。这是一个测试用例:

(defun column-summary2 (column)
  (typecase column
    (simple-double-float-vector (format t "Column is a simple-double-float-vector~%"))
    ;; (simple-integer-vector (format t "Column is a simple-integer-vector~%"))
    ;; (simple-string-vector  (format t "Column is a simple-string-vector~%"))
    ((simple-array string (*)) (format t "~A Column is a string-array~%" column))
    ((simple-array float (*)) (format t "~A is a simple-float-array~%" column))
    ((simple-array integer (*)) (format t "~A is a simple-float-array~%" column))
    (bit-vector (make-bit-vector-summary :length (length column) :count (count 1 column))))))

对于内置类型 bit-vector 以及我自己的 simple-double-float-vector 类型,这按预期工作:

(deftype simple-double-float-vector (&optional (length '*))
  "Simple vector of double-float elements."
  `(simple-array double-float (,length)))

但字符串和整数失败:

LS-USER> (df::column-summary2 #("foo" "bar" "baz"))
#(foo bar baz) Column is a string-array
NIL
LS-USER> (df::column-summary2 #(1 2 3))
#(1 2 3) Column is a string-array

我尝试为这两个定义类型:

(deftype simple-integer-vector (&optional (length '*))
  "Simple vector of integer elements."
  `(simple-array integer (,length)))

(deftype simple-string-vector (&optional (length '*))
  "Simple vector of integer elements."
  `(simple-array string (,length)))

编辑:强制似乎也失败了:

CL-USER> (type-of (coerce #(4 4 1 1 2 1 4 2 2 4 4 3 3 3 4 4 4 1 2 1 1 2 2 4 2 1 2 2 4 6 8 2) '(simple-array integer (32))))
(SIMPLE-VECTOR 32)
CL-USER> (type-of (coerce #("foo" "bar" "baz") '(simple-array string (3))))
(SIMPLE-VECTOR 3)

但这无济于事。 integerstring 似乎总是混为一谈。谁能看出为什么?

数组的类型只能是给定给 make-array 的类型作为其 :element-type,请参阅规范中的类型 simple-array。如果您使用数组文字,情况可能并非如此。

它不会在运行时检查每个元素的类型。

可以这个词暗示这也是受到数组元素类型升级的影响:只有一个固定的集合(实现定义的)数组类型,主要取决于是否有专门的表示。实际的数组元素类型是符合声明类型的集合中最特殊的。

如果你需要运行时的准确信息,你需要自己包装和标记。

typecase 只能区分实现上不同的类型,而 integerstrings 的数组不太可能。您可以通过以下方式进行测试:

(eq (upgraded-array-element-type 'integer)
    (upgraded-array-element-type 'string))

这很可能 return t。事实上,这两种类型的 upgraded-array-element-type 本身很可能是 t:可以存储一般 string 的最专业的数组与可以存储一般 [=] 的数组相同12=],因为这两种类型都确实要求数组的元素是通用指针。

这里的事情是,当 typecase 看到一个数组时,它只能调度数组的 实现 类型,而不是其他任何类型和这两种类型在许多情况下它们在概念上并不相同。