在F#中不可变

Ale*_*xan 8 f# immutability shadowing

我知道F#中的变量默认是不可变的.但是,例如在F#interactive中:

  > let x = 4;;

val x : int = 4

> let x = 5;;

val x : int = 5

> x;;
val it : int = 5
> 
Run Code Online (Sandbox Code Playgroud)

所以,我将4分配给x,然后将5分配给x并且它正在改变.这是对的吗?它应该给出一些错误或警告吗?或者我只是不明白它是如何工作的?

Asi*_*sik 14

在编写时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
Run Code Online (Sandbox Code Playgroud)

要声明一个可变变量,请在以下mutable后面添加let:

let mutable x = 5;;

val mutable x : int = 5

> x <- 6;;
val it : unit = ()
> x;;
val it : int = 6
Run Code Online (Sandbox Code Playgroud)

但你可能会问,两者之间有什么区别?一个例子就足够了:

let i = 0;
while i < 10 do
    let i = i + 1
    ()
Run Code Online (Sandbox Code Playgroud)

尽管出现了,但这是一个无限循环.所述i环路内部声明是一个不同的i隐藏了外一个.外部的一个是不可变的,所以它始终保持其值0,循环永远不会结束.写这个的正确方法是使用一个可变变量:

let mutable i = 0;
while i < 10 do
    i <- i + 1
    ()
Run Code Online (Sandbox Code Playgroud)


qeh*_*hgt 5

x没有改变,它只是被下一个声明所隐藏.例如:

> let x = 4;;
val x : int = 4
> let x = "abc";;
val x : string = "abc"
>
Run Code Online (Sandbox Code Playgroud)