1

Clojure のマップ ref のカウンターの更新に取り組んでいます。

(defn increment-key [this key]
    (dosync
        (let [value (get @this key)]
            (if (= value nil)
                (alter this assoc key (ref 1))
                (alter this assoc key (alter value inc))))))

ただし、alter value inc ステートメントが参照を失っているようです。

(defn -main [& args]
    (def my-map (ref {}))
    (increment-key my-map "yellow")
    (println my-map)
    (increment-key my-map "yellow")
    (println my-map))

どちらが印刷されますか:

$ lein run
#<Ref@65dcc2a3: {yellow #<Ref@3e0d1329: 1>}>  
#<Ref@65dcc2a3: {yellow 2}>

このシナリオで更新中に同じ参照を保持するにはどうすればよいですか?

4

1 に答える 1

3

あなたはほとんどそこにいました。以下は解決策です。の最後の行を確認してくださいincrement-key。値を変更するだけです(マップ内のキーを変更する必要はありません。あなたの例では変更された戻り値でキーが更新されていたためです) 2、alter は ref 自体ではなく、ref の新しい値を返すことを覚えておいてください)。また、def 内で def を使用しないでください。(-main 関数で) let を使用する必要があります。

(defn increment-key [this key]
    (dosync
        (let [value (get @this key)]
            (if (= value nil)
                (alter this assoc key (ref 1))
                (alter value inc)))))

(defn -main [& args]
  (let [my-map (ref {})]
       (increment-key my-map "yellow")
       (println my-map)
       (increment-key my-map "yellow")
       (println my-map)))
于 2013-04-14T09:19:55.583 に答える