2016-12-03 71 views
0
(* junk.ml *) 
let flag = ref false 

let get_flag = !flag 

let play_cards card = 
    Printf.printf "%s-clause\n" (if card >= 27 && card <= 39 then "true" else "false"); 
    (flag := if card >= 27 && card <= 39 then true else !flag); 
    Printf.printf "check: %B " get_flag; 

在UTOP,我进口junk.ml并获得此输出ocaml的裁判不保留其值

val flag : bool ref = {contents = false} val get_flag : bool = false val play_cards : int -> unit = <fun>

我叫play_cards 30;;并收到该输出:

true-clause
check: true - : unit =()

然而,当我打电话get_flag我收到false。我想知道在编写这段代码时是否有使用refs的概念,我误解了它。

回答

2

变量get_flag是在定义时!flag的值的不可变名称。你不应该期望它的价值会改变; OCaml变量具有不可变的值。

(一些值,比如flag,对于事情本身是可变的不可变的名字。换句话说,flag总是要为相同的名称,但存储在参考值,!flag,可以改变。)

您的意见指出要get_flag有不同的价值观不同的时间。得到这个结果的一种方法是将其定义为一个函数:

let get_flag() = !flag 

现在你可以调用函数,并在每个调用它在呼叫的时刻返回flag值。

# let flag = ref false 
    let get_flag() = !flag;; 
val flag : bool ref = {contents = false} 
val get_flag : unit -> bool = <fun> 
# get_flag();; 
- : bool = false 
# flag := true;; 
- : unit =() 
# get_flag();; 
- : bool = true 
0

您的代码没有意义如图所示,hearts_broken并没有定义过get_hearts_broken。但是,如果您已将这些定义置于其他地方,那么难怪您会看到您看到的结果,因为play_cards实际上并未修改flag,正如您似乎认为的那样。

我想你已经在某些时候改名为hearts_brokenflag,却忘了修复play_cards?而这恰好不会导致错误,因为你没有重新启动顶层,所以旧的定义还在?

+0

非常抱歉。我不小心复制了旧代码。我现在编辑它以'flags' – stumped

+0

@stumped替换'hearts_broken',在那个版本中,我会看到输出'check:false'。 –