89

まず、この質問が重複している可能性があることを認めます。私に知らせて。

可変性が必要な状況での一般的な「ベスト プラクティス」とは何なのか、興味があります。F# はこれに対して 2 つの機能を提供しているようです: let mutable「ほとんどの」言語で変数のように機能するバインディングと、ref明示的な逆参照を使用する必要がある参照セル (関数で作成) です。

いずれかが「強制」されるケースが 2つあり<-ます。したがって、これらのケースは非常に明確ですが、これらのシナリオ以外で独自の可変変数を作成するときに何をすべきか知りたいです。あるスタイルが他のスタイルよりも優れている点は何ですか? (おそらく、実装に関するさらなる洞察が役立つでしょう。)ref:=

ありがとう!

4

5 に答える 5

137

私はgradbotが言ったことをサポートすることしかできません-私が突然変異を必要とするとき、私は好みlet mutableます。

実装と2つの違いについては、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 }

2つのアプローチの顕著な違いはlet mutable、可変値をスタックに(C#の可変変数として)ref格納し、ヒープに割り当てられたレコードのフィールドに可変値を格納することです。これはパフォーマンスにいくらかの影響を与える可能性がありますが、私には数字がありません...

このおかげで、使用する可変値refにエイリアスを設定できます。つまり、同じ可変値を参照する2つの値を作成できます。

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!
于 2010-07-10T23:54:44.317 に答える
19

関連する質問:「ローカルの可変値はクロージャでキャプチャできないため、代わりにrefを使用する必要があるとおっしゃいました。これは、クロージャでキャプチャされた可変値をヒープに割り当てる必要があるためです(クロージャはヒープ)。」F#からref-mutable vars vs object fields

let mutable参照セルよりも好ましいと思います。個人的には、必要な場合にのみ参照セルを使用します。

私が書いたほとんどのコードは、再帰と末尾呼び出しのおかげで可変変数を使用していません。可変データのグループがある場合は、レコードを使用します。オブジェクトの場合let mutable、プライベート可変変数を作成するために使用します。私は実際には、クロージャ、通常はイベントにのみ参照セルを使用します。

于 2010-07-10T23:46:36.060 に答える
5

ブライアンによるこの記事は答えを提供するかもしれません。

Mutable は使いやすく効率的 (ラッピングなし) ですが、ラムダでキャプチャすることはできません。ref セルはキャプチャできますが、冗長で効率が低くなります (? - これはよくわかりません)。

于 2010-07-11T11:28:12.957 に答える
3

ウィキブックスの「可変データ」セクションを確認することをお勧めします。

便宜上、ここにいくつかの関連する引用があります:

mutableキーワードは、可変レコードを作成するためにレコードタイプで頻繁に使用されます

可変変数は多少制限されています。可変変数は、それらが定義されている関数のスコープ外ではアクセスできません。具体的には、これは、別の関数のサブ関数でミュータブルを参照できないことを意味します。

Refセルは、可変の制限のいくつかを回避します。実際、refセルは非常に単純なデータ型であり、レコード型の可変フィールドをラップします。

refセルはヒープに割り当てられるため、複数の機能間で共有できます

于 2010-07-10T23:53:59.280 に答える