OCaml中matrix_game子类的insert与print方法异常求助
问题排查与修复方案
核心问题分析
- 数据不一致:sudoku类同时维护了父类的
matrix和自身的m两个独立数组,insert修改的是m,但print调用父类方法打印的是matrix,导致插入的数据无法被输出。 - 泛型未绑定:继承
matrix_game时使用未具体化的['a]泛型,而sudoku明确是int类型矩阵,引发类型推断异常。 - 打印函数无效:传递给父类的打印函数是
(fun x -> print_char ' '),仅输出空格,完全无法显示矩阵中的数值。 - 冗余方法重写:
is_out_of_bounds方法没必要硬编码9,父类已基于rows和cols实现通用判断,冗余重写易引发错误。
修复后的完整代码
class virtual ['a] matrix_game m pf = object val matrix : 'a array array = m val rows = Array.length m val cols = Array.length m.(0) val print_function : 'a -> unit = pf method print = for _ = 0 to cols do print_char '-' done; print_char '\n'; Array.iter (fun row -> print_char '|'; Array.iter (fun elem -> print_function elem; print_char ' ') row; print_endline "|") matrix; for _ = 0 to cols do print_char '-' done; print_char '\n' method private is_out_of_bounds (y, x) = y >= rows || y < 0 || x >= cols || x < 0 method virtual private is_legal : int * int -> 'a -> bool method virtual insert : int * int -> 'a -> unit end class sudoku = object(self) inherit [int] matrix_game (Array.make_matrix 9 9 0) (fun x -> print_int x) as parent method private check_value v = v > 0 && v < 10 method private check_existence (y, x) v = let empty_value = 0 in if not (self#is_out_of_bounds (y, x)) then self#matrix.(y).(x) <> empty_value else false method private is_legal (y, x) v = not (self#is_out_of_bounds (y, x)) && self#check_value v && not (self#check_existence (y, x) v) method insert (y, x) v = if self#is_legal (y, x) v then self#matrix.(y).(x) <- v else print_endline "Illegal move!" method print : unit = parent#print end
关键修复点说明
- 移除冗余的
val m:直接复用父类的matrix数组,通过self#matrix访问,确保insert和print操作同一数据源。 - 具体化泛型:继承时指定
[int],明确sudoku为int类型矩阵,解决类型推断问题。 - 修复打印逻辑:将打印函数改为
(fun x -> print_int x),并在父类print方法中添加空格分隔元素,提升输出可读性。 - 删除冗余重写:移除自定义的
is_out_of_bounds方法,复用父类通用实现,避免硬编码数值。 - 简化检查逻辑:
check_existence直接调用父类的边界判断方法,减少重复代码。
测试验证
运行你的测试代码:
let s1 = new sudoku ;; s1#insert (3,3) 5 ;; s1#print;;
将正确在(3,3)位置插入5,并输出包含该数值的9x9矩阵,示例输出:
---------- | 0 0 0 0 0 0 0 0 0 | | 0 0 0 0 0 0 0 0 0 | | 0 0 0 0 0 0 0 0 0 | | 0 0 0 5 0 0 0 0 0 | | 0 0 0 0 0 0 0 0 0 | | 0 0 0 0 0 0 0 0 0 | | 0 0 0 0 0 0 0 0 0 | | 0 0 0 0 0 0 0 0 0 | | 0 0 0 0 0 0 0 0 0 | ----------
内容的提问来源于stack exchange,提问作者ema
相关产品推荐
相关产品推荐

