0

在 FSI 我输入

> let a = 10;;

val a : int = 10

> let a = a + 1;;

val a : int = 11

看起来我在这里有一个可变变量?我错过了什么吗?

4

2 回答 2

5

It is not a mutable value. But you use the shadowing : in F#, value shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope.

If you want to have a mutable value, there is a syntaxe in F# :

let mutable a = 10
a <- a + 1
于 2013-04-21T19:16:47.870 回答
5

正如 Arthur 已经解释的那样,您看到的是阴影,这意味着命名的原始“变量”a被一个也命名的新“变量”隐藏a(我在引号中使用变量,因为它们实际上是不可变的值)。

要查看差异,您可以在函数中捕获原始值,然后在隐藏原始值后打印该值:

> let a = 10;;                // Define the original 'a' value
val a : int = 10

> let f () = a;;              // A function captures the original value    
val f : unit -> int

> let a = 42;;                // Define a new value hiding the first 'a'
val a : int = 42

> f();;                       // Prints the original value - it is not mutated!
val it : int = 10

可悲的是,您不能使用完全相同的代码来查看let mutable行为方式(因为 F# 不允许在闭包中捕获可变引用),但是当您使用引用单元格(即,在堆中存储可变值的简单对象)时,您可以看到突变):

> let a = ref 10;;             // Create a mutable reference cell initialized to 10
val a : int ref = {contents = 10;}

> let f () = !a;;              // A function reads the current value of the cell    
val f : unit -> int

> a := 42;;                    // Overwrite the value in the cell with 42
val it : unit = ()

> f();;                        // Prints the new value - it is mutated
val it : int = 42

您可以在 F# 交互中逐行运行代码,但是当您复制整个片段(输入行)并将它们放在普通 F# 代码中时,它会执行完全相同的操作 - 例如,在函数或模块中。只是为了;;在 F# 交互输入中结束行(我在 F# 交互窗口中键入了代码),但在普通代码中不需要它,因为 F# 使用缩进来查找语句的结束位置。

于 2013-04-21T21:28:57.443 回答