2

編集: 私の質問の以前のバージョンを投稿した後、実際の問題はネストされた関数にあることがわかりました。

内にクロージャーがある場合、そのクロージャー内deftypeから可変フィールドを更新することはできません。

たとえば、次の作品:

(deftype Test [^:unsynchronized-mutable x]
    TestInterface
    (perform [this o] (set! x o)))

しかし、これはしません:

(deftype Test [^:unsynchronized-mutable x]
    TestInterface
    (perform [this o] (fn [] (set! x o)) nil)) ; throws a compiler error about assigning to non-mutable field

フィールドに到達してアクセスする方法はありますか? 実行(set! (.x this) o)すると、次の結果が得られます。

ClassCastException user.Test は compile__stub.user.Test user.Test/fn--152 にキャストできません (NO_SOURCE_FILE:3

コードを実行しようとしたとき。


完全を期すためのコードTestInterface:

(definterface TestInterface (perform [o]))
4

1 に答える 1

3

動作しないバージョンは、動作する場合、野生に逃げてどこからでも呼び出される可能性のあるクロージャーを返し、非同期のローカルを設定し、物事をひどく台無しにすることを考慮してください。

この種のことを行うことを主張する場合は、可変フィールドのセッターを使用していつでもインターフェイスを作成し、それを型に実装して、このフィールドを設定する必要がある場所でセッターを呼び出すことができます。

(set! (.-x foo) ...)Clojure 型の変更可能なフィールド (非同期と揮発性の両方) はプライベートであるため、直接変更 ( ) は機能しません。

于 2013-08-14T21:12:47.117 に答える