Racket 文档告诉我“如果 eq?
和 #t
引用同一个对象,则 v1
返回 v2
”,但是根据 fixnums
,=
的两个 eq?
也是相同的,=
“如果所有参数在数值上相等,则返回 #t
”。我找不到关于“数字”和“符号”的任何消息,但在我发现的示例中:
> (eq? 'yes 'yes)
#t
这和上面是矛盾的,因为上面从来没有提到
symbol
是特殊的,所以'yes
和'yes
是不一样的。这让我更加困惑:
> (eq? (expt 2 100) (expt 2 100))
#f
> (eq? (* 6 7) 42)
#t
如果数字是用数字测试的,那么
(eq? (expt 2 100) (expt 2 100))
应该返回 #t
,否则,数字通过引用测试,那么 (eq? (* 6 7) 42)
应该返回 #f
,所以我猜以上两种情况都不对......为什么?!
最佳答案
(expt 2 100)
太大而不能成为
fixnum
。让我们尝试评估:(expt 2 100) ; => 1267650600228229401496703205376
(fixnum? (expt 2 100)) ; => #f
(expt 2 10) ; => 1024
(fixnum? (expt 2 100)) ; => #t
这是因为大量数字被分配在几个存储单元中(将它们视为一组数字组的列表)。
另一方面,每个符号在阅读时都是“内化的”。这意味着第一次读取时,会为其创建一个新的符号值。随后,当再次读取时,系统会检查是否已经存在具有该名称的符号,在这种情况下,将返回旧符号值,而不会在内存中创建任何新对象。所以:
(eq 'yes 'yes) ; => #t
因为显然具有相同名称的两个不同符号实际上是内存中的同一个对象。