【发布时间】:2011-01-02 16:13:39
【问题描述】:
我在很多地方看到过 clojure 符号 -> ,但我不确定这个符号的名称和作用,甚至不确定它是否是标准 clojure 的一部分。有人可以向我解释一下吗?
【问题讨论】:
标签: clojure
我在很多地方看到过 clojure 符号 -> ,但我不确定这个符号的名称和作用,甚至不确定它是否是标准 clojure 的一部分。有人可以向我解释一下吗?
【问题讨论】:
标签: clojure
-> 使用函数调用的结果并将其按顺序发送到下一个函数调用。
所以,更简单的例子是:
(-> 2 (+ 3))
返回 5,因为它将 2 发送到下一个函数调用 (+ 3)
以此为基础,
(-> 2
(+ 3)
(- 7))
返回 -2。我们保留第一次调用的结果 (+ 3) 并将其发送到第二次调用 (- 7)。
正如@bending 所指出的,接受的答案会更好地显示 doto 宏。
(doto person
(.setFName "Joe")
(.setLName "Bob")
(.setHeight [6 2]))
【讨论】:
(+ 3) 的函数调用...而是宏将代码从(-> a b c) 重新排列为(c (b a))
这是一种从左到右编写代码的方式,而不是由内而外,例如
(reduce (map (map xs bar) foo) baz)
变成
(-> xs (map bar) (map foo) (reduce baz))
您可能想阅读源代码,它是here。
编辑:由于 amalloy,修复了我对 -> 和 ->> 的混淆。遗憾的是,我的例子现在不太可能出现在实践中。
【讨论】:
->> 的行为,而不是->。您提供的示例将扩展到(reduce (map (map xs bar) foo) baz),因为-> 穿过second 位置,而不是last(这是->> 所做的)。
直到我把它想象成这样,我才完全明白 ->(画眉或线)做了什么:
(-> 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
【讨论】:
(-> expr f1 f2 f3) ;same as (f3 (f2 (f1 expr))) 但(-> 2 (+ 3) ( - 7)) 不等于( - 7 (+ 3 2)) 第一个结果是-2 但第二个是2 你能帮我解决我的误解?
'->' 是一个宏。我认为,描述它的最佳方式是“点特殊形式”的示例,它的目的是使代码更简洁易读,如 clojure.org 网站对The Dot special form 的解释所示
(.. System (getProperties) (get "os.name"))
扩展到:
(. (. System (getProperties)) (get "os.name"))
但更易于编写、阅读和理解。另请参阅 -> 可以类似使用的宏:
(-> (System/getProperties) (.get "os.name"))
还有“doto”。假设您有一个对象,您想在其上调用多个连续的 setter。你可以使用“doto”。
(doto person
(.setFName "Joe")
(.setLName "Bob")
(.setHeight [6 2]))
在上面的示例中,setter 不返回任何内容,因此 'doto' 是合适的选择。除非设置器返回 'this',否则 -> 将无法代替 'doto'。
所以,这些是与 -> 宏相关的一些技术。我希望这不仅有助于解释它们的作用,还有助于解释它们存在的原因。
【讨论】:
你可以自己看看:
(macroexpand `(-> 42 inc dec))
【讨论】:
它被称为画眉运算符。最好解释一下here。
【讨论】:
->。 -> 和 ->> 是宏,我通常听到它们被称为“线程”宏,因为它们将第一个表单“穿过”其余的表单,从而形成一个缝合在一起的表单。