OCaml中==物理相等运算符对整数和字符串返回结果不同的原因
在OCaml中要先分清两种相等判断的区别:
=是结构相等:仅比较两个值的内容是否匹配,不关心内存存储位置==是物理相等:判断两个变量是否指向内存中的同一个存储地址,仅当两个变量是对同一块内存的引用时才返回true
为什么a == b返回true?
OCaml运行时对值的存储分两类,差异导致了两个例子的结果不同:
- 堆分配值:字符串、数组、自定义类型、ref引用等大小不固定或需要动态修改的类型,都会在堆上单独分配内存块。默认情况下OCaml不会自动驻留内容相同的字符串常量,所以你定义的两个独立的
"odg"字符串字面量,会被分配到两个不同的堆内存地址,所以x == y返回false,和你之前的理解一致。 - 立即值:整数、布尔值、字符、单位值这类大小固定、不可变的基础类型,不会在堆上分配内存,直接作为立即数存储在栈上。OCaml规定所有取值相同的立即值,物理表示完全统一,所以不管你定义多少个值为1的绑定,它们的物理地址判断都会返回true。
如何验证a和b是两个不同的let绑定?
let绑定是「变量名」到「值」的映射关系,两个绑定是否独立和它们指向的值是否物理相等没有关系。验证方式很简单:将两个绑定绑定到可变类型的值,修改其中一个绑定指向的值,观察另一个是否变化即可:
(* 用可变的ref类型代替不可变的整数 *) let a = ref 1 let b = ref 1 (* 修改a指向的ref单元格的值 *) a := 2;; (* 输出!b查看b指向的值,结果为1,没有随a的修改变化,说明a和b是完全独立的两个绑定 *) !b;;
如果a和b是同一个绑定,修改a的指向值时b的结果也会同步变化,上面的测试结果证明二者是完全独立的绑定。
另外补充一个简单的区分示例:即使两个绑定指向同一个物理值,也可以是不同的绑定:
let a = 1 let b = a (* 此时a == b返回true,因为指向同一个立即值,但a和b依然是两个独立的绑定 *)
内容的提问来源于stack exchange,提问作者aspeddro
相关产品推荐
相关产品推荐

