我的一些模块包含全局类实例,这些实例使用两个方法private_method
和public_method
实现给定的类类型。
我希望MyModule.my_instance # public_method
可以在我的计划中的任何位置使用,MyModule.my_instance # private_method
仅在MyModule
内可用。
我尝试过以下方法:
class type public_type = object
method public_method : int
end ;;
class type private_type = object
method public_method : int
method private_method : int
end ;;
let make_private : unit -> private_type = fun () -> object
method public_method = 0
method private_method = 0
end ;;
module type MY_MODULE = sig
val my_instance : public_type
end
module MyModule : MY_MODULE = struct
let my_instance = make_private ()
let _ = print_int (my_instance # private_method)
end
但是,这会导致错误:
值不匹配:
val my_instance : private_type
未包含在
中
val my_instance : public_type
我可以手动编写强制:
module MyModule : MY_MODULE = struct
let my_instance = make_private ()
let _ = print_int (my_instance # private_method)
let my_instance = (my_instance :> public_type)
end
但是我不想为这么简单的东西加倍代码大小。
您对此为何会有什么建议,以及如何解决这个问题?
答案 0 :(得分:3)
ocaml中没有隐含的强制。也许值得将强制放入仿函数(如果你有几个具有相同属性的模块):
module Hide(M:sig val my_instance : private_type end) : MY_MODULE =
struct
let my_instance = (M.my_instance :> public_type)
end
module MyModule = Hide (struct
let my_instance = make_private ()
let _ = print_int (my_instance # private_method)
end)
答案 1 :(得分:3)
解决此问题的最佳技巧可能是使用Garrigue所描述的private row types(“私人行类型:抽象未命名”;请查阅,因为我无法发布第二个链接)。这可以与显式对象类型表达式一起使用:
module type MY_MODULE2 = sig
type t = private < public_method : int; ..>
val my_instance : t
end ;;
module MyModule2 : MY_MODULE2 = struct
type t = private_type
let my_instance = make_private ()
let _ = print_int (my_instance # private_method)
end ;;
或使用对象路径(这是您需要的):
module type MY_MODULE3 = sig
type t = private #public_type
val my_instance : t
end ;;
module MyModule3 : MY_MODULE3 = struct
type t = private_type
let my_instance = make_private ()
let _ = print_int (my_instance # private_method)
end ;;