1. ホーム
  2. f#

[解決済み] F#: mutableとrefの比較

2023-04-06 09:37:33

質問

まず、この質問が重複している可能性があることを認めますが、教えてください。

私は、ミュータビリティが望まれる場合の一般的なベストプラクティスが何であるかに興味があります。F#はこのために2つの機能を提供しているようです。 let mutable これは、ほとんどの言語における変数のように動作するように思われ、また、参照セル( ref 関数で作成される) 参照セルを使用するために明示的な再参照を必要とします。

.NETの相互運用では、mutableを使用する傾向があります。 <- を使用する傾向があり、ワークフロー計算では ref:= . これらのケースはかなり明確ですが、これらのシナリオ以外で独自のミュータブル変数を作成するときはどうすればいいのか気になります。一方のスタイルが他方に対してどのような利点があるのでしょうか?(おそらく、実装に関するさらなる洞察が助けになるでしょう)。

ありがとうございます!

どのように解決するのですか?

私がサポートできるのは グラッドボット が言ったことだけを支持します。突然変異が必要なとき、私は let mutable .

の実装と違いについて -。 ref セルは基本的に、変更可能なレコードフィールドを含む非常に単純なレコードによって実装されています。自分で簡単に書くことができます。

type ref<'T> =  // '
  { mutable value : 'T } // '

// the ref function, ! and := operators look like this:
let (!) (a:ref<_>) = a.value
let (:=) (a:ref<_>) v = a.value <- v
let ref v = { value = v }

この二つのアプローチの顕著な違いは let mutable はミュータブルな値をスタックに保存するのに対し(C#ではミュータブル変数として ref はヒープで確保されたレコードのフィールドにミュータブルな値を格納します。これはパフォーマンスに何らかの影響を与えるかもしれませんが、数値は持っていません...。

このおかげで、ミュータブル値で ref を使う変異型値はエイリアスすることができます。

let a = ref 5  // allocates a new record on the heap
let b = a      // b references the same record
b := 10        // modifies the value of 'a' as well!

let mutable a = 5 // mutable value on the stack
let mutable b = a // new mutable value initialized to current value of 'a'
b <- 10           // modifies the value of 'b' only!