Я видел символ clojure → , используемый во многих местах, но я не уверен относительно того, что этот символ вызывается и делает, или даже является ли он частью стандартного clojure. Может ли кто-нибудь объяснить это мне?
Что делает → делать в clojure?
Ответ 1
Принятый ответ вводит в заблуждение.
- > использует результат вызова функции и отправляет его последовательно в следующий вызов функции.
Итак, проще будет:
(-> 2 (+ 3))
Возвращает 5, поскольку отправляет 2, на следующий вызов функции (+ 3)
Настроим это,
(-> 2
(+ 3)
(- 7))
Возвращает -2. Мы сохраняем результат первого вызова (+ 3) и отправляем его на второй вызов (- 7).
Как отмечено @bending, принятый ответ лучше показал бы макрос doto.
(doto person
(.setFName "Joe")
(.setLName "Bob")
(.setHeight [6 2]))
Ответ 2
Это способ написать код слева направо, а не изнутри, например.
(reduce (map (map xs bar) foo) baz)
становится
(-> xs (map bar) (map foo) (reduce baz))
Возможно, вы захотите прочитать источник, здесь.
EDIT: Исправлена ошибка с ->
с ->>
благодаря amalloy. К сожалению, мой пример сейчас вряд ли появится на практике.
Ответ 3
'- > ' - макрос. Лучший способ описать это, на мой взгляд, на примере "точечной специальной формы", для которой он служит для того, чтобы сделать код более кратким и разборчивым, как указано на веб-сайте clojure.org на веб-сайте Специальная форма Dot
(.. System (getProperties) (get "os.name"))
расширяется до:
(. (. System (getProperties)) (get "os.name"))
но легче писать, читать и понимать. См. Также макрос → , который можно использовать аналогично:
(-> (System/getProperties) (.get "os.name"))
Существует также "дота". Скажем, у вас есть один объект, на который вы хотели бы назвать несколько последовательных сеттеров. Вы можете использовать "doto".
(doto person
(.setFName "Joe")
(.setLName "Bob")
(.setHeight [6 2]))
В приведенном выше примере сеттеры ничего не возвращают, делая "дото" подходящим выбором. → не будет работать вместо 'doto', если сеттеры не вернут 'this'.
Итак, это некоторые методы, связанные с макросом → . Надеюсь, это поможет объяснить не только то, что они делают, но и почему они существуют.
Ответ 4
Я не полностью понял, что → (дрозд или поток), пока я не увидел его так:
(-> expr f1 f2 f3) ;same as (f3 (f2 (f1 expr)))
(-> expr ;same as form above
f1 ;just a different visual layout
f2
f3)
;this form is equivalant and shows the lists for f1, f2, f3.
(-> expr ; expr treaded into first form
(f1 ) ; | result threaded into next form
(f2 ) ; | and so on...
(f3 )) ; V the lists (f1
(f3 (f2 (f1 expr))) ;the result is the same as this
Вот несколько примеров:
(-> 41 inc dec inc) ;same as (inc (dec (inc 41)))
42
(-> 41 ;same as above but more readable
(inc )
(dec )
(inc ))
42
(inc (dec (inc 41))) ;easier to see equivalence with above form.
42
(-> 4 (* 4 3) (- 6)) ;same as (- (* 4 3 4) 6)
42
(-> 4 ; 4
(* 3 4) ; (* 4 3 4)
(- 6)) ;(- (* 4 3 4) 6)
42
(- (* 4 3 4) 6) ;easier to see equivalence with above form.
42
Ответ 5
Вы можете убедиться сами:
(macroexpand `(-> 42 inc dec))
Ответ 6
Он назвал оператора дрозда. Это лучше всего объясняет здесь.