新手问题。我正在阅读非常好的Ocaml ORA书。当我使用Marshal部分的magic_copy示例进行游戏时,我更接近浏览器而不是终端,所以我在ocsigen的toplevel in a browser中尝试了,我很惊讶地得到了结果:
(* js_of_ocaml *)
# let ora_magic_copy a =
let s = Marshal.to_string a [Marshal.Closures] in
Marshal.from_string s 0;;
val ora_magic_copy : 'a -> 'b = <fun>
# (ora_magic_copy 2 : float) +. 3.1;;
- : float = 5.1
检查ocaml 2(书籍当前版本)和ocaml 3.12.1(由我的机器上安装的顶层和js_of_ocaml使用)之间是否有变化,我在我安装的普通顶层上尝试了同样的例子机器并得到了书中解释的结果:由于类型系统检查Marshaled值而导致的段错误。
(* Linux toplevel *)
# (ora_magic_copy 3: float) +. 2.1;;
Segmentation fault (core dumped)
我只是好奇:为什么?
我看到在三种情况下,Marshal.to_string提供相同的字符串:linux编组一个int,js_of_ocaml编组和int,js_of_ocaml编组一个浮点数。奇怪的是linux toplevel marshalling float。
这是由于js_of_ocaml使用javascript的基本类型吗?或者只是......未定义的行为?
答案 0 :(得分:7)
是的,您的问题来自于您正在使用javascript进行测试。
当您使用标准ocaml
顶层时,+.
操作对OCaml浮点运算,即块内的双框,+.
的两个参数应该指向这样的盒子。在你的例子中,你给OCaml整数2
而不是一个指针(在内部,它表示为5,即2&lt;&lt; 1 + 1),所以OCaml在尝试读取应该读取的双精度时发生段错误在记忆中的位置0x5 ......
在js_of_ocaml
浏览器中,浮点数只是javascript浮点数,整数是javascript整数,+.
是javascript加法,可以添加整数和浮点数(通过自动将整数转换为浮点数) ),因为值是按其类型标记的。