F#の変数はデフォルトで不変であることを私は知っています。ただし、たとえばF#インタラクティブの場合:
> let x = 4;;
val x : int = 4
> let x = 5;;
val x : int = 5
> x;;
val it : int = 5
>
したがって、4をxに割り当て、次に5をxに割り当てると、変化します。それが正しいか?エラーや警告が表示されますか?それとも私はそれがどのように機能するのか理解していませんか?
F#の変数はデフォルトで不変であることを私は知っています。ただし、たとえばF#インタラクティブの場合:
> let x = 4;;
val x : int = 4
> let x = 5;;
val x : int = 5
> x;;
val it : int = 5
>
したがって、4をxに割り当て、次に5をxに割り当てると、変化します。それが正しいか?エラーや警告が表示されますか?それとも私はそれがどのように機能するのか理解していませんか?
あなたが書くとき、あなたは識別子を値にlet x = 3
バインドしています。同じスコープでもう一度これを行うと、同じ名前を持つため、前の識別子を非表示にする新しい識別子を宣言することになります。x
3
F# での値の変更は、破壊的な更新演算子<-
. これは、不変の値、つまり次の場合に失敗します。
> let x = 3;;
val x : int = 3
> x <- 5;;
x <- 5;;
^^^^^^
stdin(2,1): error FS0027: This value is not mutable
可変変数を宣言するには、 after を追加mutable
しlet
ます。
let mutable x = 5;;
val mutable x : int = 5
> x <- 6;;
val it : unit = ()
> x;;
val it : int = 6
しかし、この 2 つの違いは何ですか? 例は十分かもしれません:
let i = 0;
while i < 10 do
let i = i + 1
()
見た目とは裏腹に、これは無限ループです。i
ループ内で宣言されたものは、外側のものを隠す別物ですi
。外側のものは不変であるため、常にその値0
を保持し、ループが終了することはありません。これを記述する正しい方法は、変更可能な変数を使用することです。
let mutable i = 0;
while i < 10 do
i <- i + 1
()
x
is not changed, it's just hidden by next declaration.
For example:
> let x = 4;;
val x : int = 4
> let x = "abc";;
val x : string = "abc"
>
に 5 を割り当てているのではなくx
、新しい変数を定義しています。
次の例は、2 つの異なる変数があることを示しています。(また、古い x がクロージャ内にあり、別の関数で使用されている場合、「アクセス」できることも示しています):
let x = 5;;
let f y = y+x;;
f 10;;
let x = 0;;
f 10;;
収量
>
val x : int = 5
>
val f : int -> int
> val it : int = 15
>
val x : int = 0
> val it : int = 15
ご覧のとおり、 f の両方の呼び出しで最初の variable が使用されますx
。定義let x = 0;;
は新しい変数x
を定義しますが、再定義はしませんf
。
F#での識別子「シャドウイング」(つまり非表示)を示す最小限の例を次に示します。
let x = 0
do //introduce a new lexical scope
let x = 1 //"shadow" (i.e. hide) the previous definition of x
printfn "%i" x //prints 1
//return to outer lexical scope
printfn "%i" x //prints 0, proving that our outer definition of x was not mutated by our inner definition of x
F#Interactive(FSI)で作業しているため、実際の例はもう少し複雑です。FSIは、例で次のようなコードを動的に出力します。
module FSI_0001 =
let x = 4;;
open FSI_0001 //x = 4 is now available in the top level scope
module FSI_0002 =
let x = 5;;
open FSI_0002 //x = 5 is now available in the top level scope, hiding x = 4
module FSI_0003 =
let it = x;;
open FSI_0003
//... subsequent interactions