Сейчас на канале #clojure на Freenode идет обсуждение этой темы. Крис Хаузер (который собирался опубликовать ответ, но в итоге решил, что слишком занят, чтобы сделать это) опубликовал Суть , которая демонстрирует, что происходит с перегруженным методом boolean
против Object
; Оказывается, что в некоторых сценариях, в дополнение к (boolean ...)
, требуется подсказка типа. Дискуссия была довольно поучительной: несколько темных углов процесса компиляции Clojure стали хорошо освещенными. (См. Ссылки на журнал IRC ниже.)
В принципе, если объект создается прямо в форме вызова метода - (.foo (Foo.) ...)
, скажем, - подсказка типа не нужна; это также не является необходимым, если объект был создан как значение для local в форме let
(см. обновление 2 ниже и мою версию Gist). Если объект получен поиском Var, тем не менее, требуется подсказка типа - которая может быть предоставлена либо на самом Var, либо на сайте вызова, на символе, используемом для ссылки на Var.
Java-код от Gist:
package mypkg;
public class Ugly {
public Ugly(){}
public String foo(boolean i) { return "bool: " + i; }
public String foo(Object o) { return "obj: " + o; }
}
И код Clojure:
(.foo (mypkg.Ugly.) 5)
;=> "obj: 5"
(.foo (mypkg.Ugly.) true)
;=> "obj: true"
(.foo (mypkg.Ugly.) (boolean true))
;=> "bool: true"
(def u (mypkg.Ugly.))
(.foo u (boolean true))
;=> "obj: true"
(.foo #^mypkg.Ugly u (boolean true))
;=> "bool: true"
Обратите внимание, что компилятору Clojure требуется подсказка типа на u
, чтобы иметь возможность компилировать прямой вызов метода. В противном случае кажется, что генерируется основанный на отражении код, который, очевидно, теряет тот факт, что аргумент должен быть примитивом на этом пути.
Мои дополнения следуют (и вот мой форк вышеупомянутого Gist ).
;; renamed mypkg.Ugly to foo.TestInterop2 when doing my tests
user> (let [t (foo.TestInterop2.)]
(.foo t (boolean true)))
"bool: true"
;;; type-hinting the Var
user> (def #^foo.TestInterop2 x (foo.TestInterop2.))
#'user/x
user> (.foo x (boolean true))
"bool: true"
Тема была впервые поднята на данный момент . Chouser опубликовал Gist через полчаса , после чего обсуждение становится все более и более интересным.