OCaml 是否默认对不可变数据结构进行结构共享(链接)?
如果没有,是否有类似构造函数属性的东西指定何时共享实例?
不可变数据的语义使你无法判断它是否被共享。因此,实际上不可能沿着这些思路(恕我直言)提出强有力的主张。不同的实现可以做不同的事情,代码中不同地方的事情也可能不同。
但是,OCaml 在应用函数(即传递参数)和移动值(通过
let
或引用赋值)时做了显而易见的事情。换句话说,是的,OCaml 在值移动时共享结构。
然而,没有特殊的工作来检测相同的值并将它们合并。所以如果你有:
let x = (1, 2, 3) in
let y = (1, 2, 3) in
...
不保证
x
和y
的值是共享的。事实上(在我所知道的实现中),他们不会。
如果你想在这种情况下共享数据,你可以写:
let x = (1, 2, 3) in
let y = x in
...
是的,您可以在 OCaml 中共享不可变数据结构。 这可以通过称为功能更新的功能来完成,该功能在here
中进行了描述使用记录的 with 子句,您可以指定要共享记录的哪些字段。
考虑以下示例:
type t = {a: string; b: string}
let x = {a= "a"; b= "b"}
let y = {a= "a"; b= "b"}
let () = Format.print_bool (x.a == y.a) (* prints false *)
let () = Format.print_bool (x.b == y.b) (* prints false *)
在这里,我们有两个结构相同的记录,但是正如你所看到的,它们的字段在物理上是不同的,ie 不共享。
现在我们可以通过共享
y
的字段来构建x
,除了b
字段例如:
let y = {x with b= "b"}
let () = Format.print_bool (x.a == y.a) (* prints true *)
let () = Format.print_bool (x.b == y.b)
(* prints false as only the field a was shared *)
记录的内存表示或多或少包含在指向其字段的指针列表中。此操作复制指针,而不是直接复制值,因此共享。