标准 ML:对参考细胞的困惑
Standard ML: Confusion about Reference Cells
我正在阅读 Harper 的 SML 简介,对参考单元有点困惑。在第114,他举了下面的例子:
val r = ref 0
val s = ref 0
val _ = r := 3
val x = !s + !r
val t = r
val _ = t := 5
val y = !s + !r
val z = !t !r
"After execution of these bindings, x is bound to 3, y is bound to 5, and z is bound to 10."
这是我对他的代码的跟踪:
val r = ref 0 //allocates storage for r and sets to 0
val s = ref 0 //allocates storage for s and sets to 0
val _ = r := 3 //sets r = 3
val x = !s + !r //sets x = 0 + 3 = 3
val t = r //sets t = 3
val _ = t := 5 //sets t = 5
val y = !s + !r //sets y = 0 + 3 = 3
val z = !t !r //sets z = 5 + 3 = 8
我的 x 是正确的 (3),但我的 y 和 z 都是错误的(我的 y 是 3 而不是 5,我的 z 是 5 而不是 10)。
我哪里错了?
此外,为什么需要 val _ = t := 5
而不是简单的 t := 5
?
谢谢,
克莱曼
val t = r
使 t 成为 r 的 别名 。它们都指的是商店中的相同位置。因此 t := 5
具有改变 r 所指的内存位置内容的副作用(因为 t 和 r 指的是同一个地方)。因此
val y = !s + !t
设置 y = 0 + 5 = 5。
你是对的 val _ = t := 5
与 t := 5
基本相同,尽管前者抑制了 REPL 中的输出(通过丢弃赋值表达式的值)。
val t = r
不会将 t
设置为 3。它将 t
设置为与 r
相同的参考单元格。
因此,当您执行 t := 5
时,您将 t
和 r
的内容都设置为 5,因为它们包含相同的引用单元格。
关于你的另一个问题,t := 5
是函数:= : 'a ref * 'a -> unit
的函数调用。因此,t := 5
是一个计算结果为 ()
.
的表达式
val _ = t := 5
简单地丢弃了 ()
并将其变成声明而不是表达式。
我正在阅读 Harper 的 SML 简介,对参考单元有点困惑。在第114,他举了下面的例子:
val r = ref 0
val s = ref 0
val _ = r := 3
val x = !s + !r
val t = r
val _ = t := 5
val y = !s + !r
val z = !t !r
"After execution of these bindings, x is bound to 3, y is bound to 5, and z is bound to 10."
这是我对他的代码的跟踪:
val r = ref 0 //allocates storage for r and sets to 0
val s = ref 0 //allocates storage for s and sets to 0
val _ = r := 3 //sets r = 3
val x = !s + !r //sets x = 0 + 3 = 3
val t = r //sets t = 3
val _ = t := 5 //sets t = 5
val y = !s + !r //sets y = 0 + 3 = 3
val z = !t !r //sets z = 5 + 3 = 8
我的 x 是正确的 (3),但我的 y 和 z 都是错误的(我的 y 是 3 而不是 5,我的 z 是 5 而不是 10)。
我哪里错了?
此外,为什么需要 val _ = t := 5
而不是简单的 t := 5
?
谢谢, 克莱曼
val t = r
使 t 成为 r 的 别名 。它们都指的是商店中的相同位置。因此 t := 5
具有改变 r 所指的内存位置内容的副作用(因为 t 和 r 指的是同一个地方)。因此
val y = !s + !t
设置 y = 0 + 5 = 5。
你是对的 val _ = t := 5
与 t := 5
基本相同,尽管前者抑制了 REPL 中的输出(通过丢弃赋值表达式的值)。
val t = r
不会将 t
设置为 3。它将 t
设置为与 r
相同的参考单元格。
因此,当您执行 t := 5
时,您将 t
和 r
的内容都设置为 5,因为它们包含相同的引用单元格。
关于你的另一个问题,t := 5
是函数:= : 'a ref * 'a -> unit
的函数调用。因此,t := 5
是一个计算结果为 ()
.
val _ = t := 5
简单地丢弃了 ()
并将其变成声明而不是表达式。