2016-12-03 34 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'。 –