The short answer is that it is for performance. When passing an argument to a function it is either passed as an integer or a pointer. At a machine level language level there is no way to tell if a register contains an integer or a pointer, it is just a 32 or 64 bit value. So the OCaml run time checks the tag bit to determine if what it received was an integer or a pointer. If the tag bit is set, then the value is an integer and it is passed to the correct overload. Otherwise it is a pointer and type is looked up.
另外,您不能将这样的整数对象传递给 CPU 来执行快速整数算术。如果要添加两个整数,则 真的只有两个指针,它们指向要添加的两个整数对象的对象标题的开头。因此,首先需要对第一个指针执行整数运算,将偏移量添加到存储整数数据的对象中。那你就得取消对那个地址的引用。对第二个整数再次执行相同操作。现在您有两个整数,您实际上可以要求 CPU 添加。当然,现在需要构造一个新的整数对象来保存结果。
What do we do with those other address spaces? Well, typical examples include encoding floats in the other large address space and a number of special objects like true, false, nil, the 127 ASCII characters, some commonly used short strings, the empty list, the empty object, the empty array and so on near the 0 address.
例如,在 MRI、 YARV 和 Rubinius Ruby 解释器中,整数按照我上面描述的方式进行编码,false被编码为地址 0(恰好 还有是 false在 C 中的表示) ,true被编码为地址 2(恰好 true的 C 表示移动了一位) ,nil被编码为 4。
OCaml 运行时允许通过统一
每个 OCaml 值表示为一个单独的
这样就有可能只有一个实现,例如,
“ list of things”,带有要访问的函数(例如 List.length)和
构建(例如 List.map)这些列表,它们的工作方式是否相同
是整数列表、浮点数列表或整数集列表。
Anything that does not fit in in a word is allocated in a block in the
表示该数据的单词就是指向该块的指针。
由于堆只包含单词块,所以所有这些指针都是
对齐: 它们的少数最低有效位总是未设置。
无参数构造函数(如下所示: type water = Apple | Orange |
香蕉)和整数不能表示如此多的信息,以至于它们
需要在堆中分配。它们的表示形式是未装箱的
数据直接位于单词的内部,否则这个单词就会是
因此,当一个列表列表实际上是一个指针列表时,一个
整型数列表包含少了一个间接的整型数
访问和构建列表的函数不会注意到,因为 int 和
指针的大小相同。
不过,垃圾收集者需要
able to recognize pointers from integers. A pointer points to a
定义为活的堆中的格式良好的块(因为它是
being visited by the GC) and should be marked so. An integer can have
如果不采取预防措施,可能会意外地看到
像一个指针。这可能导致死块看起来是活的,但很多
worse, it would also cause the GC to change bits in what it thinks is
活动块的头部,当它实际上跟随一个整数时
看起来像个指针,搞乱了用户数据。
这就是为什么未装箱的整数提供31位(对于32位 OCaml)或63位(对于
64-bit OCaml) to the OCaml programmer. In the representation, behind
场景,包含整数的单词的最低有效位
总是设置为31位或63位,以便与指针区分
整数是相当不寻常的,所以任何使用 OCaml 的人都知道
OCaml 的用户通常不知道的是为什么没有一个
用于64位 OCaml 的63位非装箱浮动类型。