2

我的几个模块包含全局类实例,它们使用两种方法实现给定的类类型,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 

但我宁愿不要将这样简单的代码大小加倍。

您对为什么会发生这种情况以及我如何解决它有什么建议吗?

4

2 回答 2

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)
于 2011-01-10T14:05:06.647 回答
3

解决此问题的最佳技术可能是使用Garrigue 所描述的私有行类型(“私有行类型:抽象未命名”;请查看它,因为我无法发布第二个链接)。这可以与显式对象类型表达式一起使用:

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  ;;
于 2011-01-28T14:56:08.820 回答