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,有一点不同,我已经用这种行为背后的原因更新了我的答案。希望对你有帮助。