Подтвердить что ты не робот

Что делает → делать в clojure?

Я видел символ clojure → , используемый во многих местах, но я не уверен относительно того, что этот символ вызывается и делает, или даже является ли он частью стандартного clojure. Может ли кто-нибудь объяснить это мне?

4b9b3361

Ответ 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

Он назвал оператора дрозда. Это лучше всего объясняет здесь.