我在 OCaml 中有一个坐标“类”(使用返回对象文字的工厂函数实现),我试图弄清楚如何将该对象上的方法的可见性限制在它定义的模块中。
这是源文件
(* coordinate.ml *)
type coordinate = < get_x : int; get_y : int >
let create_coord ~x ~y = object
val x = x
val y = y
method get_x = x
method get_y = y
(* hide this method from public interface *)
method debug_print = Printf.printf "(x=%d, y=%d)\n"
end
这是界面
(* coordinate.mli *)
(* the type synonym coordinate is compatible with the "real"
* type, but does not expose the debug_print method *)
type coordinate = < get_x : int; get_y : int >
val create_coord : x:int -> y:int -> coordinate
我的意图是让 create_coord
返回的对象在 Coordinate
模块的主体内显示所有方法。 coordinate
类型别名在 .ml
文件中重复的唯一原因是为了满足编译器/允许它在 .mli
中使用.
但是,我想阻止此模块的使用者使用 debug_print
方法。我认为,“由于 OCaml 支持结构类型”,就类型归属而言,具有严格较少方法的对象类型将是“兼容”类型。
但是,当我尝试编译文件时出现以下错误:
$ ocamlc coordinate.mli
$ ocamlc coordinate.ml
File "coordinate.ml", line 1:
Error: The implementation coordinate.ml
does not match the interface coordinate.cmi:
Values do not match:
val create_coord :
x:'a ->
y:'b ->
< debug_print : int -> int -> unit; get_x : 'a; get_y : 'b >
is not included in
val create_coord : x:int -> y:int -> coordinate
File "coordinate.ml", line 3, characters 4-16: Actual declaration
Exit 2
有没有办法限制 debug_print
在 Coordinate
之外的可见性,同时使其在内部可以自由访问?
最佳答案
我认为最好的解决方案是使用私有(private)行类型:
module M : sig
type t = private < x : int; y : int; .. >
val make : int -> int -> t
val f: t -> unit
end = struct
type t = < x : int; y : int; z : [`Not_exposed] >
let make x y = object
method x = x
method y = y
method z = `Not_exposed
end
let f o =
(* Access a method not exposed outside of the module *)
assert (o#z = `Not_exposed)
end;;
这样,您不需要任何强制功能。尽管如此,任何类型 t
的对象都可以在模块 M 中看到其私有(private)方法,但只有公共(public)方法(x
和 y
)可以外部访问。在 manual 中查找更多信息.
关于types - 使用显式类型将对象中的方法的可见性限制为定义它的模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47314755/