可变记录字段和{x with ...}

Mik*_*uel 5 ocaml record mutable semantics

我一直在阅读ocaml文档,但我不能解释如何{ x with ... }解决可变字段的问题.我发现最接近的人

6.7表达式

expr := ...
    ? { expr with  field =  expr  { ; field =  expr }  [;] }
Run Code Online (Sandbox Code Playgroud)

...

记录

该表达式{ expr with field1 = expr1 ; … ; fieldn = exprn }构建一个fields field1 … fieldn等于的新记录expr1 … exprn,并且所有其他字段具有与记录中相同的值expr.换句话说,它返回记录的浅表副本expr,但field1 … fieldn初始化为的字段除外expr1 … exprn.

"浅拷贝"措辞可以解释为mutable未提及的字段共享存储空间或可以引用嵌套记录.当我测试时(使用"The OCaml toplevel,版本4.00.1")因此

type t = { mutable x : int; mutable y: int }
let a = {x=42;y=123}
let b = { a with y=124}
let _ = a.x <- 43
let _ = Printf.printf "b.x=%d\n" b.x
;;
Run Code Online (Sandbox Code Playgroud)

我得到一个结果,表明b.x没有别名a.x:

b.x=42
type t = { mutable x : int; mutable y : int; }
val a : t = {x = 43; y = 123}
val b : t = {x = 42; y = 124}
Run Code Online (Sandbox Code Playgroud)

这让我很开心,但我想确保这一点

{ e with fi=x }
Run Code Online (Sandbox Code Playgroud)

对于类似的东西来说,它是有效的语法糖

(let tmp=e in { f0=tmp.f0; … fi-1=tmp.fi-1; fi=x; fi+1=tmp.fi+1; …; fn=tmp.fn })
Run Code Online (Sandbox Code Playgroud)

并且该mutable字段不能由ref实现可以重用而不是分配新的可变存储来支持.

new*_*cct 3

在我见过的所有地方,“浅复制”都意味着,就像通过赋值一样简单地传输所有组件,即使是在所有字段始终可变的语言中,如 Java。所以在这种情况下(let tmp=e in { f0=tmp.f0; \xe2\x80\xa6 fi-1=tmp.fi-1; fi=x; fi+1=tmp.fi+1; \xe2\x80\xa6; fn=tmp.fn })这正是它应该表达的意思。

\n

  • @Mike:在 OCaml 中,“t ref”是“{mutable content : t}”的糖(如手册中某处所述),因此您可以安全地假设“mutable”不是通过“ref”间接定义的。;) (4认同)