2012-11-07 8 views
5

私はocamlドキュメントを読んできましたが、変更可能なフィールドの周りで{ x with ... }がどのように動作するかを説明する部分はありません。 closest I've found氏は述べています可変レコードフィールドと{x with ...}

6.7式

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

...

レコード

表現{ expr with field1 = expr1 ; … ; fieldn = exprn }expr1 … exprnに等しいfields field1 … fieldn新鮮なレコードを構築し、他のすべてのフィールドが同じを持ちますレコードexprと同じ値です。換言すれば、expr1 … exprnに初期化されたフィールドfield1 … fieldnを除いて、レコードexprシャローコピーを返します。

「シャローコピー」という言葉は、言及されていないフィールドがストレージスペースを共有しているか、ネストされたレコードを参照できる可能性があると解釈できます。私は

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 
;; 

ので(「バージョン4.00.1をOCamlのトップレベル」を使用して)テストするとき、私は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によって新しい変更可能な記憶域を割り当てるのではなく、再利用することができます。

+1

だから、あなたはちょうど私達が は '{Fi付きのeは= X}' が効果的に '({F0 = tmp.f0にTMP = Eを聞かせための糖衣構文であることを確認したい; ... FI-1 = TMP。 fi = x; fi + 1 = tmp.fi + 1; ...; fn = tmp.fn}) '... etc ...? –

+0

@RobertHarvey、他のドキュメントへのポインタ、またはこれらのドキュメントの読み方の説明は参考になりますが、何が未定義の動作であるかを知っている人からの何かが助けになります。 –

答えて

3

「浅いコピー」とは、Javaのようにすべてのフィールドが常に変更可能な言語であっても、すべてのコンポーネントを割り当てのように転送することを意味します。したがって、この場合は(let tmp=e in { f0=tmp.f0; … fi-1=tmp.fi-1; fi=x; fi+1=tmp.fi+1; …; fn=tmp.fn })が意味するとおりです。

+0

もし 'mutable'が' ref'を使って構文的砂糖として実装されていたならば、 '{mutable i:int}'は '{i:int ref}'と '{i = 42}'の構文糖です。 '{i = ref 42}'の構文砂糖を使うと、浅いコピーがrefセルをコピーします。変更可能なレコードフィールドが、レコードの外に存在するエイリアス可能な 'ref'への不変ポインタかどうかを指定する、ドキュメントのセクションを見つけることができません。 –

+4

@Mike:OCamlでは、 't ref'は' {可変内容:t} 'の砂糖です(マニュアルのどこかに書かれているように)。' mutable'は 'refによって間接的に定義されていないと思います'。 ;) –

+0

@AndreasRossberg、素晴らしい。 'mutable'レコードフィールドは、他の抽象化が構築される変更可能な記憶プリミティブです。どうもありがとう。記録のために、手動参照は[2。2 Mutable](http://caml.inria.fr/pub/docs/u3-ocaml/ocaml-core.html#mutable)「OCamlでは、参照は基本的ではなく、可変の特殊なケースです記録。"それは[Pervasives ocamldoc](http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#TYPEref)に再掲されています。 –

関連する問題