Ocaml 具有可变字段的记录是否始终为';通过引用传递';?

Ocaml 具有可变字段的记录是否始终为';通过引用传递';?,ocaml,Ocaml,从我到目前为止所观察到的情况来看,具有可变字段的记录的行为就像它们总是通过引用传递一样。例如,如果我将记录传递给函数或将其存储在数据结构中,则该记录不会在过程中被复制。例如,此代码: type t = { mutable t_val: int } let () = let ht = Hashtbl.create 16 in let x = { t_val = 42 } in Hashtbl.replace ht "x" x; x.t_val <-

从我到目前为止所观察到的情况来看,具有可变字段的记录的行为就像它们总是通过引用传递一样。例如,如果我将记录传递给函数或将其存储在数据结构中,则该记录不会在过程中被复制。例如,此代码:

type t = {
    mutable t_val: int
}

let () =
    let ht = Hashtbl.create 16 in
    let x = { t_val = 42 } in
    Hashtbl.replace ht  "x" x;
    x.t_val <- 43;
    let x2 = Hashtbl.find ht "x" in
    Format.printf "x.t_val: %d, x2.t_val: %d@." x.t_val x2.t_val

这是可靠的预期行为还是取决于具体情况?

是的,这是可靠的预期行为。事实上,不仅可变记录是“通过引用传递”,所有记录都是。只有使用不变的数据,您才不会注意到差异。(有一个例外:像
int
这样的小的不可变数据被优化为按值传递的方式处理。但是,从语义上来说,您可以安全地假设一切都像是一致地按引用传递一样工作。)

这与按值传递或按引用传递无关。例如,Java只有传递值,当您传递引用时,在函数内部,它们还可以修改引用所指向的对象的字段,并且这些更改对具有相同对象引用的任何其他人都可见

(按值传递和按引用传递之间的区别在于直接指定给参数变量(不访问指向它的对象或任何其他对象)时会发生什么情况)在函数内部;在“传递值”中,它对调用范围内传递的变量没有影响;在“传递引用”中,它与对调用范围内传递的变量的赋值具有相同的效果。在OCaml中,在初始化后无法直接赋值给变量(根本没有语法),因此,按值传递和按引用传递之间没有区别。)

您所说的是记录类型是引用类型,即记录类型的值实际上是对基础结构的引用,多个引用可以指向同一基础结构,通过一个引用进行的修改可以通过对同一基础结构的其他引用看到。这是真的。正如@kne所提到的,OCaml中唯一没有“装箱”的类型,即引用类型,是简单的不可变类型,比如
int
,或者可以放入
int
,因为它们是不可变的,所以它们是引用类型还是值类型基本上没有区别(可能除了
==
之类的语义之外)

x.t_val: 43, x2.t_val: 43