5

我一直在阅读ocaml文档,但我无法解释如何{ x with ... }围绕可变字段工作的部分。我发现的最接近的说

6.7 表达式

expr := ...
    ∣ { expr with  field =  expr  { ; field =  expr }  [;] }

...

记录

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

这种“浅拷贝”措辞可以被解释为意味着mutable未提及的字段共享存储空间或可以引用嵌套记录。当我测试(使用“OCaml 顶层,版本 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
;;

我得到的结果表明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}

这让我很高兴,但我想确保

{ e with fi=x }

是有效的语法糖,例如

(let tmp=e in { f0=tmp.f0; … fi-1=tmp.fi-1; fi=x; fi+1=tmp.fi+1; …; fn=tmp.fn })

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

4

1 回答 1

3

在我所见的任何地方,“浅拷贝”意味着,就像通过赋值一样简单地转移所有组件,即使在所有字段总是可变的语言中,比如 Java。所以在这种情况下(let tmp=e in { f0=tmp.f0; … fi-1=tmp.fi-1; fi=x; fi+1=tmp.fi+1; …; fn=tmp.fn })正是它应该的意思。

于 2012-11-08T01:38:46.550 回答