Во-первых, в стороне.
Что касается макросов defn
против defn-
, 2-я форма - это просто сокращение для «частных» функций. Полная форма выглядит следующим образом:
(defn ^:private foo [args] ...)
Тем не менее, это всего лишь подсказка для пользователя, что не следует использовать эти функции. Для тестирования и т. Д. Легко обойти это слабое «личное» ограничение. Из-за хлопот я никогда не использую так называемые «частные» функции (иногда я использую метаданные ^:no-doc
и такие имена, как foo-impl
, чтобы указать, что fn не является частью общедоступного API и должен игнорироваться пользователями библиотеки).
Функция "main" в программе Clojure
В Java программа всегда запускается с помощью вызова "главная »функция в выбранном классе
class Foo
public static void main( String[] args ) {
...
}
}
, а затем
> javac Foo.java ; compile class Foo
> java Foo ; run at entrypoint Foo.main()
Clojure выбирает имя начальной функции -main
. Дефис в имени функции -main
на самом деле не является особенным, за исключением того, что делает его необычным, поэтому он менее вероятно конфликтует с любой другой функцией в вашей кодовой базе. Вы можете увидеть это в определении функции clojure.main/main-opt
.
Вы можете увидеть часть происхождения соглашения о гипене в документах для gen-class
(прокрутите вниз, чтобы увидеть часть о :prefix
). Обратите внимание, что использование дефиса можно изменить, если использовать gen-class
для взаимодействия с Java.
Используя инструменты Clojure Deps & CLI , имя -main
предполагается в качестве начальной точки программы.
Если вы используете Leiningen, он более гибкий и позволяет переопределить точку входа -main
программы.
В проектах Leiningen запись, подобная следующей, указывает нас чего начать, когда вы наберете lein run
:
; assumes a `-main` function exists in the namespace `demo.core`
:main ^:skip-aot demo.core
, поэтому в такой программе:
(ns demo.core )
(defn foo [& args]
(newline)
(println "*** Running in foo program ***")
(newline))
(defn -main [& args]
(newline)
(println "*** Running in main program ***")
(newline))
мы получаем нормальное поведение:
~/expr/demo > lein run
*** Running in main program ***
Однако мы могли бы вызвать программу другим способом:
> lein run -m demo.core/foo
*** Running in foo program ***
, чтобы сделать функцию foo
«точкой входа». Мы также можем изменить настройку :main
следующим образом:
:main ^:skip-aot demo.core/foo
и получить поведение:
~/expr/demo > lein run
*** Running in foo program ***
Итак, имея начальную функцию программы Clojure с именем -main
является значением по умолчанию и требуется для большинства инструментов. Вы можете переопределить значение по умолчанию, если используете Leiningen, хотя это, вероятно, полезно только при тестировании и разработке.
Помните, что каждое пространство имен может иметь свою собственную функцию -main
, поэтому вы можете легко изменить исходную функциюпросто путем изменения начального пространства имен, которое вызывается.
И, наконец, дефис в -main
нас не связан с дефисом, используемым для псевдо-частных функций, определенных с помощью defn-
.