`def` vs` declare` для форвардной декларации
Clojure, имеет макрос declare
, который позволяет вам пересылать функции или переменные. Кажется, он функционирует точно как def
: Оба (declare x)
и (def x)
создают #<Unbound Unbound: #'user/x>
Когда следует использовать (declare x)
вместо (def x)
?
Ответы
Ответ 1
Оба declare
и def
действительно создают несвязанный var, но есть 3 преимущества использования declare
:
- Вы можете создать несколько варов в одном выражении, например.
(declare x y z)
- Классы отмечены дополнительными метаданными
{:declared true}
- Использование слова
declare
возможно более ясное и идиоматическое
(source declare)
:
(defmacro declare
"defs the supplied var names with no bindings, useful for making forward declarations."
{:added "1.0"}
[& names] `(do [email protected](map #(list 'def (vary-meta % assoc :declared true)) names)))
Ответ 2
В документации дается ответ:
=> (doc declare)
-------------------------
clojure.core/declare
([& names])
Macro
defs the supplied var names with no bindings, useful for making forward declarations.
Рассматривая реализацию, ясно, что declare
определяется в терминах def
и предоставляет немного синтаксического сахара. Так функционально, они почти одинаковы.
Преимущество declare
- показать намерение для более позднего читателя. (declare x y z)
означает, что я намеревался сделать повторное объявление этих символов, потому что макрос useful for making forward declarations.
(def x) (def y) (def z)
означает, что я интернирую эти символы, но вы не знаете, намерен ли я давать им определения и забывать, или делаю ли я декларации вперед или, может быть, что-то еще тонкое.
Итак, (declare x)
должно быть предпочтительнее, чем (def x)
, когда вы делаете объявление вперед, чтобы проявить милосердие к будущим читателям вашего кода.
Ответ 3
def
всегда применяется к привязке к корню, даже если var связан с потоком в точке, где вызывается def
.
def
дает сам var (а не его значение). Выдает исключение, если символ уже находится в пространстве имен и не сопоставляется с интернированным var.
Объявить def
предоставленные имена переменных без привязок, полезных для внесения деклараций вперед.