在普通的 lisp 中,使用 '#(...) 或仅使用 #(...) 创建向量有什么区别吗?

In common lisp, is there any difference to create a vector using '#(...) or just #(...)?

在 Common Lisp (SBCL) 中,可以在 # 之前使用 ' 创建向量(数组),也可以不使用:

CL-USER> '#(a b c)
#(A B C)

CL-USER> #(a b c)
#(A B C)

很明显,它们似乎生成了同一个对象。在这些表达式上使用 type-ofdescribe 后,它们 return 相同的信息:

CL-USER> (type-of #(a b c))
(SIMPLE-VECTOR 3)
CL-USER> (type-of '#(a b c))
(SIMPLE-VECTOR 3)
CL-USER> (describe #(a b c))
#(A B C)
  [simple-vector]

Element-type: T
Length: 3
; No value
CL-USER> (describe '#(a b c))
#(A B C)
  [simple-vector]

Element-type: T
Length: 3
; No value

相等也是一样的(同equalp):

CL-USER> (equalp '#(a b c) #(a b c))
T

但与 equal 不同:

CL-USER> (equal '#(a b c) #(a b c))
NIL

' 而不是 导致上述结果 [​​=22=]:

CL-USER> (equal '#(a b c) '#(a b c))
NIL

创建数组时使用一种方法而不是另一种方法是否有任何实际后果?

谢谢。

引用

为了消除任何混淆,'#(a b c) 以撇号开头,它引用了一个值;这与 (quote #(a b c)) 相同。引用计算为被引用的文字值。

CL-USER> '3
3
CL-USER> 'a
A
CL-USER> '#(a b c)
#(a b c)

文字

通常,引用一个表达式并对其求值不会给出相同的值。例如:

CL-USER> (equalp '(vector 1) (vector 1))
NIL

上面,'(vector 1) 计算为两个值的列表(一个符号和一个数字),但 (vector 1) 计算为一个元素的向量。

然而,对于文字值,无论是否被引用,它们都具有相同的值:

CL-USER> (= '3 3)
T

文字向量#(a b c)的行为相同,都是自求值。读取表单时,reader 创建一个矢量对象。这样的对象评估为自身:

CL-USER> (eval #(a b c))
#(a b c)

等于

这里使用equal可以出人意料,但是结果符合定义:

Two arrays are equal only if they are eq, with one exception: strings and bit vectors are compared element-by-element (using eql).

在这里你不操作字符串或位向量,所以你只测试身份,就像你使用 EQ 一样。但是你有两个不同的向量实例,一次被引用,一次不被引用,它们很可能是两个不同的向量(但是 EQ (因此, EQUAL 也是)可能是 T 具有不同的编译器)。

结论

Is there any practical consequences of using one approach instead of the other when creating arrays?

我不这么认为,你通常不引用数字,数组字面量也是如此。

注意。至于所有文字值,你不应该改变它们,它们是常量值。