Reference 在OCaml中复制构造?
OCaml值通过引用传递,而不是通过值传递。当值为常数时,参考值和值之间没有明显差异。但是,当值是可变的(例如具有可变字段的结构)时,我可能希望复制它,以便当一个变量改变值时,设置为前一个变量的另一个变量也不会改变。我可以在OCaml中执行此操作吗?恐怕没有自动简便的方法。您必须通过自己编写一些代码来复制一个值。比如说,Reference 在OCaml中复制构造?,reference,copy,ocaml,Reference,Copy,Ocaml,OCaml值通过引用传递,而不是通过值传递。当值为常数时,参考值和值之间没有明显差异。但是,当值是可变的(例如具有可变字段的结构)时,我可能希望复制它,以便当一个变量改变值时,设置为前一个变量的另一个变量也不会改变。我可以在OCaml中执行此操作吗?恐怕没有自动简便的方法。您必须通过自己编写一些代码来复制一个值。比如说, type t = { x : int option; mutable y : int option } let copy t = { t with x = t.x } le
type t = { x : int option; mutable y : int option }
let copy t = { t with x = t.x }
let () =
let t = { x = None; y = Some 1 } in
let t' = copy t in
t.y <- None;
assert (t'.y <> None) (* check t'.y is not shared *)
type t={x:int-option;可变y:int-option}
让我们复制t={t和x=t.x}
让()=
设t={x=None;y=some1}in
让t'=将t复制进来
t、 y引入可变值有三种语法方法:
- 定义具有可变字段的记录李>
- 使用一些预定义的可变容器,如Array、Bytes、Bigarray李>
- 定义一个具有可变字段的类
一个函数可以克隆它们
除非您愿意依赖不安全的Obj
模块或使用Marshal
模块,否则不存在这样的函数,它将接受任何值并返回其克隆。因此,在纯OCaml中,不可能获得另一个值的逐位拷贝,因为OCaml试图从应用程序中抽象其二进制表示。如果您确实需要,那么以下低效的实施可能足以满足您的需要:
let clone (type t) (x : t) : t =
let buf = Marshal.(to_bytes x [No_sharing; Closures]) in
Marshal.from_bytes buf 0
它不适用于不支持封送的值,例如文件描述符,以及不实现封送接口的自定义对象(用C实现)
可变记录
没有所有记录都属于的基类型。因此,对于每个具有可变类型的记录,您需要提供自己的克隆器,或者您可以依赖上面的clone
函数
预定义容器
所有预定义的容器都提供克隆函数,但是,由于它们都属于不同的类型,因此没有通用函数来处理它们
可变对象
面向对象编程总是与可变性紧密相连。因此,OCaml提供了适用于所有对象的Oo.copy
函数,因为所有其他对象都属于一种对象类型
。因此,如果您确实需要一个通用的克隆函数,那么考虑使用对象。 谢谢!在with构造中,复制值的字段是否指向堆上的相同位置,或者它们是否保证引用其他内容?如果是这样,“x=t.x”步骤是否是一种优化,以使不可变字段指向同一堆位置?是否确定Obj.dup是递归的?没有文档,obj.c中caml_obj_dup中的代码似乎不是递归的。