Standard ML中变量重绑定后函数引用变量的行为疑问
重新绑定变量后函数行为的原因解析
先看你测试的代码:
val x = 2; (* val x = 2 : int *) fun addx y = y + x; (* val addx = fn : int -> int *) addx(5); (* val it = 7 : int *) val x = 5; (* val x = 5 : int *) addx(5); (* val it = 7 : int *) fun subx y = y - x; (* val subx = fn : int -> int *) subx(7); (* val it = 2 : int *) 3 + x; (* val it = 8 : int *) addx(10); (* val it = 12 : int *)
这种行为的核心原因是Standard ML采用词法作用域(静态作用域)——函数会捕获自己定义时所在环境中的变量绑定,而非调用时的变量绑定。
当你定义
addx函数时,当前环境里的x绑定的是值2。addx内部的x会固定指向这个绑定,后续执行val x = 5只是在当前环境创建了一个全新的x绑定,和addx已经捕获的旧绑定完全无关。所以哪怕之后x被重新绑定为5,调用addx(5)依然是5 + 2 = 7,调用addx(10)就是10 + 2 = 12。定义
subx函数时,当前环境的x已经是5了,所以subx捕获的是这个新的x绑定。调用subx(7)时,自然是7 - 5 = 2。直接执行
3 + x得到8,是因为这里直接使用了当前环境中最新的x绑定(值为5),和函数内部捕获的绑定不是同一个东西。
总结来说:函数记住的是自己“定义那一刻”看到的变量绑定,不是调用时的变量绑定。
内容的提问来源于stack exchange,提问作者Rick Schuh
相关产品推荐
相关产品推荐

