从“现实世界Ocaml ”第24页(请参阅https://realworldocaml.org/v1/en/html/a-guided-tour.html#for-and-while-loops)。代码是:
# let find_first_negative_entry array =
let pos = ref 0 in
while !pos < Array.length array && array.(!pos) >= 0 do
pos := !pos + 1
done;
if !pos = Array.length array then None else Some !pos
;;
val find_first_negative_entry : int array -> int option = <fun>
# find_first_negative_entry [|1;2;0;3|];;
- : int option = None
# find_first_negative_entry [|1;-2;0;3|];;
- : int option = Some 1
和
# let find_first_negative_entry array =
let pos = ref 0 in
while
let pos_is_good = !pos < Array.length array in
let element_is_non_negative = array.(!pos) >= 0 in
pos_is_good && element_is_non_negative
do
pos := !pos + 1
done;
if !pos = Array.length array then None else Some !pos
;;
val find_first_negative_entry : int array -> int option = <fun>
# find_first_negative_entry [|1;2;0;3|];;
Exception: (Invalid_argument "index out of bounds").
作者声称:
附带说明一下,前面的代码利用了&&,OCaml的And运算符发生短路的事实。特别是,在形式为expr1 && expr2的表达式中,只有在expr1计算为true时,才会对expr2进行评估。如果不是那样的话,那么前面的函数将导致越界错误。实际上,我们可以通过重写函数以避免短路来触发越界错误:”
但是我仍然不太明白为什么第一个代码可以正常工作,而第二个代码却得到异常。我已编译,两个函数的行为均符合预期。但是我很困惑为什么第二个功能不起作用,因为它也使用了&&命令,并且除了None以外,它也没有处理任何否定项。
这是评估的顺序。在第一个功能中,Term1 && Term2
允许&&
短路行为来保护我们免受Term2的侵害。在第二个示例中,总是在测试发生之前评估let绑定。因此,无法防止Term2的不良行为。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句