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