我试图从here创建和使用堆栈对象(修改为具有字符串):
let s = object
val mutable v = [""; ""]
method pop =
match v with
| hd :: tl ->
v <- tl;
Some hd
| [] -> None
method push hd =
v <- hd :: v
end ;;
let () =
s#push "first";
s#push "second";
s#push "third";
print_endline s#pop; (* error from this line *)
print_endline s#pop;
print_endline s#pop;
但是,我遇到以下错误:
$ ocaml objects.ml
File "./objects.ml", line 19, characters 15-20:
Error: This expression has type string option
but an expression was expected of type string
我无法理解错误:如果期望的类型是字符串,为什么不接受字符串类型的表达式?
答案 0 :(得分:3)
我无法理解错误:如果期望的类型是字符串,为什么不接受字符串类型的表达式?
因为表达式s#pop
的类型为string
。其类型为string option
,即Some s
或None
,其中s
的类型为string
。
看一下pop
方法的实现,如果堆栈中有更多元素等待,则返回Some s
;如果堆栈为空,则返回None
method pop =
match v with
| hd :: tl ->
v <- tl;
Some hd (* returns `Some hd` *)
| [] -> None (* returns `None` *)
您可以实现一个辅助函数,该函数将打印string option
类型的值,例如
let print_some s = match s with
| None -> print_endline "empty"
| Some s -> print_endline s
使用方法
let () =
s#push "first";
s#push "second";
s#push "third";
print_some s#pop;
print_some s#pop;
print_some s#pop;
这里是stack
对象的一些替代实现,它们使用其他方式与调用方进行通信,以告知栈为空,例如,来自栈元素域(由用户提供)的哨兵值,异常或result
类型,并带有字符串错误的参数。
let stack_with_sentinel empty = object
val mutable v = []
method pop = match v with
| hd :: tl ->
v <- tl;
hd
| [] -> empty
end
let stack_with_exception = object
val mutable v = []
method pop = match v with
| hd :: tl ->
v <- tl;
hd
| [] -> raise Not_found
end
let stack_with_result = object
val mutable v = []
method pop = match v with
| hd :: tl ->
v <- tl;
Ok hd
| [] -> Error "empty stack"
end
还有许多其他方法来定义它,但是最常用的是使用option
类型。