Ответ 1
Обсуждение продолжается в канале # clojure на Freenode только сейчас по этой теме. Крис Хаузер (который собирался опубликовать ответ, но в конечном итоге решил, что он слишком занят, чтобы сделать это) опубликовал Gist, который демонстрирует, что происходит с a boolean
vs. Object
перегруженный метод; выясняется, что в некоторых сценариях в дополнение к приложению (boolean ...)
требуется подсказка типа. Дискуссия была довольно интересной, и несколько темных уголков процесса компиляции Clojure стали красиво освещены. (См. Ссылки на журнал IRC ниже.)
В принципе, если объект создается прямо в форме вызова метода - (.foo (Foo.) ...)
, скажем - этот тип подсказки не требуется; также не требуется, если объект был сконструирован как значение для локального в прилагаемой форме 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
для компиляции прямого вызова метода. В противном случае создается код, основанный на отражении, который, по-видимому, проигнорирует тот факт, что аргумент должен быть примитивным на этом пути.
Мои дополнения следуют (и здесь моя вилка вышеупомянутого Гиста).
;; 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 , и обсуждение стало более интересным после этого.