Как передать печатную коллекцию из clojure в java? - PullRequest
16 голосов
/ 11 сентября 2010

Я знаю основы взаимодействия clojure / java: вызов java из clojure и наоборот. Однако я не смог вернуть набранную коллекцию из clojure в java. Я пытаюсь увидеть что-то подобное List<TypedObject> из кода Java, который вызывает clojure.

Java Object:

public class TypedObject {
    private OtherType1 _prop1;
    public OtherType1 getProp1() {
        return _prop1;
    }
    public void setProp1(OtherType1 prop1) {
        _prop1 = prop1;
    }
}

CLojure method:

(defn -createListOfTypedObjects
      "Creates and returns a list of TypedObjects"
      [input]
      ;Do work here  to create and return list of TypedObjects
      [typedObj1, typedObj2, typedObj3])

(:gen-class
 :name some.namespace
 :methods [createListofTypedObjects[String] ????])

Давайте рассмотрим, что я пишу API с использованием clojure, который должен распространяться как jar-файл для использования из java. Мой вопрос был действительно, как к тому, что перейти на место ???? знаки вопроса выше внутри: gen-class для AOT, так что программист, пишущий фрагмент кода на Java с использованием моего API, может иметь соответствующий intellisense / завершение кода (например: createListofTypedObjects() returns List<TypedObject>) из затмения, например. *

Ответы [ 3 ]

20 голосов
/ 22 сентября 2010

Другие правы в том, что Clojure не обеспечивает типы элементов в возвращаемых коллекциях и т. Д. (На самом деле, JVM также не обеспечивает типы элементов в коллекциях - это полностью обрабатывается javac.)

Однако я вижу ценность предоставления API другим программистам на Java, которое определяет интерфейс, который объявляет, что возвращаемые значения (или параметры) параметризованы различными способами;это особенно привлекательно, если кто-то хочет использовать Clojure в существующей среде Java без создания волн.

В настоящее время требуется двухэтапный процесс:

  • определяет отдельный интерфейс (в Java!) который задает параметризованные типы так, как вам нравится
  • определяет ваше gen-class пространство имен (или proxy или reify экземпляр) таким образом, что он реализует этот интерфейс

(Clojureдействительно предоставляет форму definterface, которая позволит вам избежать отдельного определения интерфейса Java, но definterface, как и остальная часть Clojure, не предусматривает указание параметризованных типов. Может быть, когда-нибудь ...: -))

например,

public interface IFoo {
    List<TypedObject> createListOfTypedObjects ();
}

, а затем ваше пространство имен gen-класса:

(ns your.ns.FooImpl
  (:gen-class
    :implements [IFoo]))
(defn -createListOfTypedObjects
  []
  [typedObj1, typedObj2, typedObj3])

Когда ваши пользователи создают экземпляры FooImpl, они, например, получат завершение кода, указывающее, чтометод возвращает List<TypedObject>, а не Object или непараметризованный тип List.

Если вы используете нормальные инструменты сборки (например, maven , gradle или правильно настроенный муравей),затем вы можете поместить Java-интерфейс в ваш проект Clojure, и о межъязыковой зависимости позаботятся.

11 голосов
/ 11 сентября 2010

Если вы пытаетесь передать что-то вроде List<String> в метод java, вам не нужно об этом беспокоиться.Параметр типа (например, String) используется только компилятором javac, поэтому любой List будет отлично работать во время выполнения.определенного типа объекта (например, String[]), тогда вы можете использовать различные -array функции:

user=> (make-array String 10)            ; an empty String array
#<String[] [Ljava.lang.String;@78878c4c>
user=> (into-array ["foo" "bar"])        ; array type inferred from first element
#<String[] [Ljava.lang.String;@743fbbfc>
user=> (into-array Number [1.2 5 7N])    ; explicit type array
#<Number[] [Ljava.lang.Number;@7433b121>
10 голосов
/ 11 сентября 2010

Вам не нужно беспокоиться о дженериках (типизированных коллекциях) в Clojure.Дженерики - это просто подсказки типов для компилятора Java.В работающей Java-программе List<String> фактически совпадает с List<Object>.

Так, например, вектор Clojure, содержащий строки, уже является List<String> без преобразования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...