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

时间:2017-03-16 13:59:40

标签: 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 <- 43;
    let x2 = Hashtbl.find ht "x" in
    Format.printf "x.t_val: %d, x2.t_val: %d@." x.t_val x2.t_val

输出

x.t_val: 43, x2.t_val: 43

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

2 个答案:

答案 0 :(得分:2)

是的,它是可靠的和有意的。事实上,不仅可变记录通过引用传递,一切都是。只有使用不可变数据,您才会发现差异。 (有一个例外:像int这样的小型不可变数据经过优化,可以按值传递方式进行处理。但是,从语义上讲,你可以放心地假设一切都像是一直通过参考一样工作。)

答案 1 :(得分:0)

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

(传递值和传递引用之间的区别在于当您直接分配给参数变量(不访问指向它的对象或其他任何内容)时发生的情况函数;在pass-by-value中,它对调用范围中传递的变量没有影响;在pass-by-reference中,它与调用范围中传递的变量的赋值具有相同的效果。在OCaml中,它在初始化之后不可能直接分配给变量(根本就没有这样做的语法),因此,传值和传递引用之间没有区别。)

你所说的是记录类型是引用类型,即记录类型的值实际上是对底层结构的引用,多个引用可以指向相同的底层结构,并且可以看到通过一个引用的修改通过对同一底层结构的其他引用。这是真的。正如@kne所提到的,OCaml中唯一没有&#34;盒装&#34;的类型,即引用类型,是简单的不可变类型,如int或可以适合int的东西,因为它们是不可变的,所以它们是引用类型还是值类型(除了==之类的语义之外)几乎没有区别。