gas*_*che 18
是的,它显然没有故意记录.对于Obj我看到的五种用途(或写自己,这更令人不安),其中两种是不合理的,其中两种是避免更清洁的设计变更的方法,无论如何都是有用的,其中一种是真正的"好"解决"一个复杂的问题.
Obj仅公开允许探索和操纵OCaml数据的运行时表示的类型中断操作.你不需要这些函数的文档,它们是显而易见的,但你需要了解OCaml数据表示(我使用这个文档学习它,但ocaml手册也记录了它),如果你想入侵它你应该知道运行时知道什么是安全的,什么不是.作为一般规则:不要.
以下是Obj的一些合法用法:
将Coq程序编译为OCaml程序时; Coq类型系统功能更强大,它可以键入OCaml拒绝的内容,因此Coq-> Ocaml转换器插入Obj.magic调用以强制OCaml接受其输出.
当在OCaml 3.x中编码GADT时,它不支持它 - 它们被添加到4.00.有一个模块级相等和函子的编码(参见本文或本文),但更常见的一个(在menhir解析器生成器中使用,它是ocamlyacc的一个很好的替代品,请参阅本文(PDF))使用Obj.魔法
使用某种(自制)运行时类型信息编组数据时.MarshalOCaml 的模块已经不是类型安全的(出于显而易见的原因),并且如果您需要在不同的上下文中进行不同类型的编组(例如,来自/来自查询和SQL服务器的结果,就像我在我的猕猴项目中所做的那样))你需要某种不安全的演员.
小智 10
该模块Obj基本上处理堆中OCaml值的结构和解释.如果您想了解这意味着什么,您必须阅读OCaml手册第18章 "将C与Objective Caml连接".
之所以没有证件是双重的:首先,这些功能非常不安全.根本没有类型的总函数,'a -> 'b所以你可以看到,Obj.magic如果要返回任何东西,它必须做很多.事实上,它只是进入类型系统的一个洞,一个"杀死它的许可证".其次,该模块允许您随意查看和戳入堆中,实际上提供了C指向void的道德等价物.这与无限制的演员表一起让您可以从OCaml做任何您想做的事情.
但是,有合法的用途Obj.我计算了100多个Obj.magic来源,最值得注意的是代码Printf和Scanf.另一个合法用途是尾递归列表操作,前提是您可以证明代码是类型安全且线程安全的.
如果你不介意自我插头,这里有一个不安全操作的例子,它包含在一个安全的界面中,连同一个证明("因为每一步的利弊细胞都是新鲜的......")它确实是安全的,这是另一个.