在普通的 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-of
和 describe
后,它们 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?
我不这么认为,你通常不引用数字,数组字面量也是如此。
注意。至于所有文字值,你不应该改变它们,它们是常量值。
在 Common Lisp (SBCL) 中,可以在 #
之前使用 '
创建向量(数组),也可以不使用:
CL-USER> '#(a b c)
#(A B C)
CL-USER> #(a b c)
#(A B C)
很明显,它们似乎生成了同一个对象。在这些表达式上使用 type-of
和 describe
后,它们 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?
我不这么认为,你通常不引用数字,数组字面量也是如此。
注意。至于所有文字值,你不应该改变它们,它们是常量值。