Ale*_*exT 0 variables ocaml functional-programming function shadowing
我的教授今天向我们展示了这段代码,但我似乎无法理解它的结果:
# let a = 2;;
val a : int = 2
# let f = fun x -> fun y -> if x = y then a + 2 else a - 10;;
val : f 'a -> 'a -> int = <fun>
# f 1 (2 - 1);;
- : int = 4
# let a = 18;;
val a : int = 18
# f 1 (2 - 1);;
- : int = 4
Run Code Online (Sandbox Code Playgroud)
??? 所以基本上,我希望看到这个结果:
- : int = 20
Run Code Online (Sandbox Code Playgroud)
为什么这不是输出?
这是因为let a确实引入了一个具有相同名称的新变量,但该函数仍然引用其范围内的变量- 它是一个闭包,它关闭的变量是一个常量.它不会在调用它的范围内动态查找变量名称.
您可以通过在可以分配给的变量中存储可变引用来实现预期的行为:
# let a = ref 2;;
let f = fun x -> fun y -> if x = y then !a + 2 else !a - 10;;
f 1 (2 - 1);;
- : int = 4
# a := 18;;
f 1 (2 - 1);;
- : int = 20
Run Code Online (Sandbox Code Playgroud)
但是,请注意,这通常是不希望的.变量应该是常量,这样我们就可以争论函数f总是返回4或者8在调用时返回,而不是让结果取决于将值分配给参考单元的位置和时间.尽可能避免使用它们.在这个特定的例子中,人们可以这样做:
let f a x y = 2 + if x = y then 2 else -10 in
let g = f 2 in
print_int (g 1 (2-1));
let h = f 18 in
print_int (h 1 (2-1));;
Run Code Online (Sandbox Code Playgroud)