当我想返回布尔值时,我遇到了一个问题,但我总是得到错误(下面的代码)
错误:该表达式具有类型unit,但期望的是类型bool
method addVehicle licensePlate : bool =
let isSuccess = ref false in
try
(* get current time to make sure unique id *)
id <- int_of_float (Unix.time ());
(* ask to what kind of vehicle to input *)
let kind = ref 0 in
let quit_loop = ref false in
while not !quit_loop do
print_string "What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? ";
kind := read_int ();
if !kind == 0 then
(vehicle <- new car licensePlate 60;
quit_loop := true;)
else if !kind == 1 then
(vehicle <- new car licensePlate 60;
quit_loop := true;)
else if !kind == 2 then
(vehicle <- new wheelchair licensePlate 60;
quit_loop := true;)
else if !kind == -1 then
quit_loop := true
else
print_endline "Invalid vehicle!"
(* match !kind with
| 0 -> vehicle <- new car licensePlate 60; quit_loop := true;
| 1 -> vehicle <- new motorbike licensePlate 60; quit_loop := true;
| 2 -> vehicle <- new wheelchair licensePlate 60; quit_loop := true;
| -1 -> quit_loop := true;
| _ -> print_endline "Invalid vehicle!"; *)
done;
(* ask start time *)
if not (!kind == -1) then
let quit_loop = ref false in
while not !quit_loop do
print_string "Input start time (format yyyy-MM-dd hh:mm): ";
let input = read_line () in
try
let (year, month, day, hour, minute) = sscanf input "%d-%d-%d %d:%d" (fun x y z t w -> (x, y, z, t, w)) in
startTime <- snd (mktime {
tm_sec = 0; tm_min = minute; tm_hour = hour; tm_mday = day;
tm_mon = month - 1; tm_year = year - 1900; tm_wday = 0; tm_yday = 0; tm_isdst = false;
});
quit_loop := true;
isSuccess := true;
with
| _ -> print_string "Invalid start time!";
done;
with
| _ -> print_string "Something went wrong when adding vehicle";
match isSuccess with
| _ -> !isSuccess;
我想解决这个问题,使我的方法返回布尔值!
首先,OCaml中的等式为=
,如果a
和b
不是可变值,则不指定结果a == b
。你想写a=b
.
第二,你误用了;
:;
在OCaml中不是终止符,它是一种二进制运算符。
第三,你的缩进是在欺骗你。你的代码读作
with
| _ ->
(print_string "Something went wrong when adding vehicle";
match isSuccess with
| _ -> !isSuccess)
,当你可能想写
(try ...
with
| _ -> print_string "Something went wrong when adding vehicle"
);
match isSuccess with
| _ -> !isSuccess
第四,我建议将你的方法拆分为分隔良好的函数:这将使早期发现编程和语法错误变得容易得多。特别是,应该尽可能避免使用宽try ... with ...
子句,因为它隐藏了异常的来源。
作为octachron答案的补充,考虑一个简单的函数,它允许您提示车辆类型。非常简单的尾部递归,当输入与提供的任何选项都不匹配时发生。
let rec prompt_for_vehicle_type () =
print_string "What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? ";
let kind = read_int () in
match kind with
| -1 | 0 | 1 | 2 -> kind
| _ ->
print_endline "Invalid vehicle!";
prompt_for_vehicle_type ()
现在,我可以简单地调用这个函数,而不是在我的程序的主逻辑中创建一个循环,它将只返回一个有效的选择,然后可以对该选择进行模式匹配以确定如何继续。
# prompt_for_vehicle_type ();;
What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? 4
Invalid vehicle!
What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? 7
Invalid vehicle!
What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? 2
- : int = 2
#
在另一个层面上,我们可以使用模块对其进行泛化,并添加限制尝试次数的功能。由于在没有有效选择的情况下可能会达到限制,因此函数应该返回一个选项类型。
module Q = struct
module M = Map.Make (String)
let rec prompt_n n msg err opts =
if n < 0 then None
else (
print_endline msg;
M.iter (Printf.printf "%s. %sn") opts;
let input = read_line () in
if M.mem input opts then Some input
else (
print_endline err;
prompt_n (n-1) msg err opts
)
)
end
并尝试调用10次:
Q.prompt_n 10 "What kind of vehicle?" "Invalid vehicle!"
Q.M.(empty |> add "0" "Car" |> add "1" "Motobike"
|> add "2" "Wheelchair" |> add "-1" "Exit")
下一个级别是使用函子抽象出输入的类型,例如,我们可以像提示int型一样轻松地提示字符串。
module type Q_SIG = sig
type t
val compare : t -> t -> int
val input : unit -> t
val print : t -> unit
end
module Q (S : Q_SIG) = struct
module M = Map.Make (S)
type key_t = S.t
let rec prompt_n n msg err opts =
if n < 0 then None
else (
print_endline msg;
M.iter (fun k v -> S.print k; Printf.printf ". %sn" v) opts;
let input = S.input () in
if M.mem input opts then Some input
else (
print_endline err;
prompt_n (n-1) msg err opts
)
)
end
let module P = Q(struct
type t = int
let compare = compare
let input = read_int
let print = print_int
end) in
P.prompt_n 10 "What kind of vehicle?" "Invalid vehicle!"
P.M.(empty |> add 0 "Car" |> add 1 "Motobike"
|> add 2 "Wheelchair" |> add ~-1 "Exit")