2016-12-03 3 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; 

その値を保持ない、私はjunk.mlをインポートし、この出力OCamlのレフリーがutopで

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

を受けた私はplay_cards 30;;と呼ばれ、この出力を受け取っ:

true-clause
私はget_flag呼ばれたときに0

はしかし、私はfalseを受けました。私はこのコードを書いている間に私が誤解しているリファレンスを使用するという概念があるのだろうかと思っていました。

答えて

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_brokenget_hearts_brokenが定義されることはありません、あなたのコードでは、意味がありません。しかし、あなたがどこかにこれらの定義を行った場合、あなたが想定しているように見えるようplay_cardsは、実際に、flagを変更しませんので、あなたが、あなたが見ている結果を見るのも不思議ではありません。

いつかhearts_brokenからflagに名前を変更しましたが、play_cardsを修正するのを忘れましたか?そして、あなたはトップレベルを再起動しなかったのでエラーは発生しなかったので、古い定義がまだ残っていましたか?

+0

私は非常に残念です。私は誤って古いコードをコピーしました。 false'のを予想されるように:私は '私は、出力は'チェックしてくださいそのバージョンで、 – stumped

+0

@stumpedをflag'と 'hearts_broken'を置き換えるために、今、それを編集しました。 –