2013-08-14 2 views
2

EDIT: После публикации предыдущей версии моего вопроса я обнаружил, что настоящая проблема связана с вложенными функциями.Установка изменяемого поля в вложенной функции - deftype - clojure

Если у меня есть замыкание в пределах deftype, я не могу обновить какие-либо изменяемые поля из этого закрытия.

E.g. следующие работы:

(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/п - 152 (NO_SOURCE_FILE:. 3

При попытке запустить код


Код для TestInterface для полноты:

(definterface TestInterface (perform [o])) 
+0

Вы можете включить TestInterface, чтобы я мог запустить пример? –

+0

@ArthurUlfeldt Я обновил вопрос и добавил TestInterface. –

+0

Это похоже на ошибку? какая версия clojure? –

ответ

2

Считают, что версия, которая не работает, если это сработает, верните закрытие, которое могло бы сбежать в дикую природу и получить вызов из любой точки, что очень затрудняет настройку ваших несинхронизированных локальных и беспорядочных вещей.

Если вы настаиваете на выполнении такого рода действий, вы всегда можете создать интерфейс с установщиком для вашего изменяемого поля, реализовать его в своем типе и вызвать сеттер везде, где вам нужно установить это поле.

Непосредственная мутация ((set! (.-x foo) ...)) не будет работать, поскольку изменяемые поля типов Clojure (как несинхронизированные, так и неустойчивые) являются частными.

Смежные вопросы