Clojure-идиоматический способ инициализации объекта Java

Я пытаюсь найти Clojure-идиоматический способ инициализации объекта Java. У меня есть следующий код:

(let [url-connection
      (let [url-conn (java.net.HttpURLConnection.)]
        (doto url-conn
          (.setDoInput true)
          ; more initialization on url-conn
          )
        url-conn)]
  ; use the url-connection
  )

но это кажется очень неуклюжим.

Как лучше создать объект HttpURLConnection и инициализировать его, прежде чем использовать его позже в коде?

ОБНОВЛЕНИЕ. Кажется, здесь может пригодиться (doto ...):

(let [url-connection
        (doto (java.net.HttpURLConnection.)
          (.setDoInput true)
          ; more initialization
          ))]
  ; use the url-connection
  )

Согласно документам doto, он возвращает значение, которое он «делает».


person Ralph    schedule 30.11.2010    source источник


Ответы (2)


Как объяснено в обновлении моего вопроса, вот ответ, который я придумал:

(let [url-connection
        (doto (java.net.HttpURLConnection.)
          (.setDoInput true)
          ; more initialization
          ))]
  ; use the url-connection
  )

Может кто придумает лучше.

person Ralph    schedule 01.12.2010
comment
Что еще вы хотите больше? Код настолько минимален, насколько вы можете получить. - person kotarak; 01.12.2010
comment
@kotarak: Сейчас я читаю Land of Lisp Конрада Барски, доктора медицины (очень хорошая книга!). Я, конечно, не эксперт по Clojure, но когда я читаю его примеры, я уже вижу, насколько проще (и эффективнее) будет выполнять реализации в Clojure, используя карты, наборы и векторы вместо просто списков, как в традиционных Общий Лисп. - person Ralph; 02.12.2010
comment
Я не читал книгу Барски, но в CL есть массивы и хеш-таблицы. И я думаю, что, по крайней мере, на данный момент Clojure может быть трудно сравниться с эффективностью более быстрых реализаций CL. - person Tagore Smith; 02.12.2010
comment
Но я бы также сказал, что подход Clojure к типам данных намного более последователен, чем подход CL. ИМХО, эта часть Clojure разработана лучше, чем соответствующие биты CL. - person Tagore Smith; 02.12.2010
comment
Нельзя сбрасывать со счетов эффективность JVM. Он делает некоторые феноменальные оптимизации. Хотя LISP были предметом многих университетских исследовательских проектов, я должен думать, что SUN (SNORCLE) и Java Community Process создали современный движок. Clojure получает их бесплатно. Однако shootout.alioth.debian.org/u64/ поддерживает то, что вы говорите. - person Ralph; 02.12.2010
comment
Да, Java стала на удивление быстрой (по крайней мере, в основном языке). Меня не удивит, если Clojure со временем окажется быстрее во многих вещах, чем, скажем, SBCL. - person Tagore Smith; 02.12.2010
comment
Скорость — это еще не все. Я думаю, что различные литеральные синтаксисы, которые вводит Clojure, или его постоянные структуры данных более важны. Они приходят с ценой скорости, ну и что? - person kotarak; 03.12.2010
comment
И не слишком верьте бенчмаркам. Я получил структуру данных с произвольным доступом, написанную на Clojure, со скоростью вектора Clojure с произвольным доступом, написанную на Java. Судите по своему приложению, а не по зловещим микротестам. Часто они вообще ничего не доказывают. (Конечно: Clojure, скорее всего, будет работать медленнее, если алгоритм подразумевает мутацию. Но является ли это типичным случаем использования Clojure?) - person kotarak; 03.12.2010
comment
Вы правы в том, что для многих вещей сверхэффективность не так уж важна (хотя бывают случаи, когда это важно, и я рад видеть, что много усилий уходит на то, чтобы сделать Clojure эффективным). прокомментирован главным образом потому, что из многих книг о CL может сложиться неправильное впечатление. Вы можете программировать в CL очень ориентированным на списки способом (и это будет довольно неэффективно для некоторых вещей), но это еще не все. Производство CL обычно выглядит совсем иначе. - person Tagore Smith; 03.12.2010
comment
И я должен добавить, что я, безусловно, согласен с вами в том, что такие вещи, как литеральный синтаксис и особенно хорошая абстракция последовательностей в Clojure, действительно могут сделать многие вещи в Clojure намного лучше. Я не думаю, что кто-то, кто много использовал CL, связал бы это со словом совершенство ;). У CL много недостатков, и хотя многие из них становятся довольно неважными после того, как вы познакомитесь с языком, некоторые остаются раздражающими — в некоторых случаях даже очень. Но при этом, по крайней мере для меня, ни Clojure, ни CL строго не доминируют друг над другом. CL может многое предложить, несмотря на бородавки. - person Tagore Smith; 03.12.2010
comment
Вы всегда можете добавить еще несколько серверов за своим приложением, но вы не можете привлечь к проекту произвольное количество людей, поэтому я думаю, что важность фактора выразительности языка в большинстве случаев перевешивает важность эффективности. И поскольку мне не нужно использовать круглые скобки для всего, Clojure уже более удобен для меня, чем CL. - person Adam Arold; 23.08.2013

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

Единственное, что вы можете сделать, это обернуть все это в функцию, подобную этой:

(defn init-url-conn [doInput ...other params..] 
     (let [url-conn (java.net.HttpURLConnection.)]
        (doto url-conn
          (.setDoInput true)
          ; more initialization on url-conn
          )
        url-conn))

И позвоните с помощью:

(let [url-connection
      (let [url-conn (init-url-con true ...other params..)]
  ; use the url-connection
  )

Однако это зависит от объекта и действительно полезно, только если вы инициализируете объект этого класса более одного раза.

Также вы можете написать макрос, который принимает все имена методов и параметры и делает это. Но при вызове этот вызов будет не намного короче, чем ваш первый пример.

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

person Goran Jovic    schedule 30.11.2010
comment
да. И документ для doto имеет аналогичный пример: (doto (new java.util.HashMap) (.put "a" 1) (.put "b" 2)) - person Goran Jovic; 30.11.2010