Как написать публичное поле объекта Java в Clojure?

Этот вопрос отвечает на вопрос, как читать общедоступное поле из объекта Java:

(let [p (java.awt.Point.)]
  (.x p))  ; <- returns 0

Я думал, что могу написать поле аналогичным образом:

(let [p (java.awt.Point.)]
  (.x p 42))

Но я получаю следующую ошибку:

IllegalArgumentException No matching method found: x for class java.awt.Point
clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)

person Michael    schedule 14.09.2018    source источник


Ответы (1)


Это описано в Clojure — Java Interop:

(set! (. instance-expr instanceFieldName-symbol) expr)

Задание специальной формы.

Когда первый операнд является формой доступа к члену поля, присваивается соответствующее поле. Если это поле экземпляра, выражение экземпляра будет оценено [и назначено соответствующему полю экземпляра].

Также обратите внимание на использование «-» в разрешении поля:

Если вторым операндом [из (. instance-expr member)] является символ, начинающийся с -, символ-член будет разрешаться только как доступ к полю (никогда как метод нулевой арности) и предпочтительнее em> когда это и есть намерение...

Таким образом:

(set! (. p -x) 42)

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

(set! (.-x p) 42)
person user2864740    schedule 14.09.2018