为何F#中(y:=!y+1 ;!y) + !y与!y + (y:= !y+1 ; !y)结果不同?
为什么OCaml中加法表达式的求值顺序会影响带引用的计算结果?
核心原因是OCaml对二元运算符的操作数采用严格的左到右求值顺序,而引用(ref)是可变状态,操作数的求值顺序不同,会导致可变状态的修改时机不同,最终影响计算结果。
我们拆解两个例子具体看:
第一个表达式:(y:=!y+1 ;!y) + !y
- OCaml会先计算左边的操作数
(y:=!y+1 ;!y):- 序列表达式
;会先执行前半部分y:=!y+1,把引用y的值从0改成1; - 然后返回后半部分
!y的结果,也就是1。
- 序列表达式
- 接着计算右边的操作数
!y,此时y已经被改成1,所以结果是1。 - 最后相加:
1 + 1 = 2。
第二个表达式:!y + (y:= !y+1 ; !y)
- OCaml先计算左边的操作数
!y,此时y的值还是初始的0,所以结果是0。 - 再计算右边的操作数
(y:=!y+1 ;!y):- 执行
y:=!y+1把y从0改成1; - 返回
!y的结果1。
- 执行
- 最后相加:
0 + 1 = 1。
简单说就是:加法运算会先算左边的数,再算右边的数。如果左边的计算修改了引用的值,右边的计算就会用修改后的值;如果左边没修改,右边才修改,左边用的就是初始值——这就是顺序不同结果不同的根本原因。
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

