Class 如何使用OCaml中的类类型强制类中的val在类中不可变
假设我有这个:Class 如何使用OCaml中的类类型强制类中的val在类中不可变,class,types,ocaml,Class,Types,Ocaml,假设我有这个: class type point_t = object val x : int method getx : int method move : int -> unit end;; 我可以写一个这样的类,它会工作: class point : point_t = object val mutable x = 0 method getx
class type point_t =
object
val x : int
method getx : int
method move : int -> unit
end;;
我可以写一个这样的类,它会工作:
class point : point_t =
object
val mutable x = 0
method getx = x
method move d = x <- x + d
end;;
类点:点=
对象
val可变x=0
方法getx=x
方法move d=x这是不可能的,因此如果您不想允许实现使用可变变量,最好将其全部隐藏并公开函数getter/setter:
class type point_t = object(self)
method get_x : int
method with_x : int -> self
method move : int -> self
end;;
如果只允许通过move
方法进行更新,则可以使用_x
方法省略
其原因是,具有可变变量版本的类是具有相同变量的不可变版本的类的适当子类,因为它具有相同的操作集,再加上一个-设置变量的能力。因此,对类型点的任何抽象都可以应用于具有或不具有可变性的类实例(尽管它不能改变变量)。请注意,相反的情况是不可能的,如果您将使用可变的x
定义类类型point\t
,并尝试使用不可变的x来实现它,则类型系统将抱怨。因为您的实现并没有提供所有的操作
还有一件事你可能会错过。尽管如此,类point
有一个可变变量x
,但该可变性实际上是由类型约束point\t
密封的(即隐藏的)。因此,无论实现是什么,接口都严格定义为具有不可变的x
:
class the_point = object
inherit point
method! move d = x <- x - d
end
method! move d = x <- x - d
^^^^^^^^^^
Error: The instance variable x is not mutable
class\u点=对象
继承点
方法!move d=x我觉得很奇怪,在点t中val x和val mutable x之间的权限没有区别,但我想可能真的不需要它。几周前刚开始学习OCaml。谢谢@J-Lab,有一点不同,我已经用这种行为背后的原因更新了我的答案。希望对你有帮助。