【发布时间】:2013-12-17 22:39:55
【问题描述】:
我读到 F# 中的值是不可变的。但是,我也遇到了重新定义值定义的概念,它影响了之前的定义。这与可变值有何不同?我问这不仅仅是作为一个理论结构,而且是否有任何关于何时使用可变值以及何时重新定义表达式的建议;或者如果有人可以指出后者不是惯用的 f#。
重定义的基本示例:
let a = 1;;
a;; //1
let a = 2;;
a;; //2
更新 1:
除了下面的答案之外,Fsharp 交互在顶层的重新定义只允许在不同的终端中。以下内容也会在 fsi 中引发错误:
let a = 1
let a = 2;;
Error: Duplicate definition of value 'a'
另一方面,在 let 绑定中允许重新定义。
更新 2: 实际区别,闭包不能与可变变量一起使用:
let f =
let mutable a = 1
let g () = a //error
0
f;;
更新 3:
虽然我可以使用 refs 来模拟副作用,例如:
let f =
let a = ref 1
let g = a
a:=2
let x = !g + !a
printfn "x: %i" x //4
f;;
我看不出重定义和使用 mutable 关键字之间的实际区别,除了使用闭包的区别,例如:
let f =
let a = 1
let g = a
let a = 2
let x = g + a
printfn "x: %i" x //3
f;;
对
let f =
let mutable a = 1
let g = a
a <-2
let x = g + a
printfn "x: %i" x //3
f;;
另一个思路:我不确定如何使用线程,但是 (a) 另一个线程可以在 let 绑定中改变可变变量的值,并且 (b) 另一个线程可以重新绑定/重新定义一个值let 绑定中的名称。我肯定在这里遗漏了一些东西。
更新 4: 最后一种情况的不同之处在于,突变仍然会发生在嵌套范围内,而嵌套范围内的重新定义/重新绑定将“遮蔽”外部范围的定义。
let f =
let mutable a = 1
let g = a
if true then
a <-2
let x = g + a
printfn "x: %i" x //3
f;;
对
let f =
let a = 1
let g = a
if true then
let a = 2
printfn "a: %i" a
let x = g + a
printfn "x: %i" x //2
f;;
【问题讨论】:
标签: f# functional-programming immutability mutability