私は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
によって新しい変更可能な記憶域を割り当てるのではなく、再利用することができます。
だから、あなたはちょうど私達が は '{Fi付きのeは= X}' が効果的に '({F0 = tmp.f0にTMP = Eを聞かせための糖衣構文であることを確認したい; ... FI-1 = TMP。 fi = x; fi + 1 = tmp.fi + 1; ...; fn = tmp.fn}) '... etc ...? –
@RobertHarvey、他のドキュメントへのポインタ、またはこれらのドキュメントの読み方の説明は参考になりますが、何が未定義の動作であるかを知っている人からの何かが助けになります。 –