简体   繁体   English

Clojure的->和->>宏

[英]Clojure's -> and ->> macro

Clojure's ->> macro thread the form from the last argument, when -> form from the first. Clojure的->>宏从最后一个参数传递线程形式,而->则从第一个参数传递形式。

user=> (->> a (+ 5) (let [a 5]))
10

However, I get an exception when I used the operations exchanged. 但是,使用交换的操作时会出现异常。

user=> (-> a (let [a 5]) (+ 5))

CompilerException java.lang.IllegalArgumentException: let requires a vector for its binding in user:1, compiling:(NO_SOURCE_PATH:1:7) 

Furthermore, I expect these two operations will get me the same results, which is not. 此外,我希望这两个操作将获得相同的结果,但事实并非如此。

user=> (-> 0 (Math/cos) (Math/sin))
0.8414709848078965
user=> (->> 0 (Math/sin) (Math/cos))
1.0

What's wrong? 怎么了? How's the -> and ->> macros work? ->->>宏如何工作?

The -> macro inserts the argument as the first argument for the given function, not giving the argument to the last function. ->宏将参数作为给定函数的第一个参数插入,而不是将参数赋予最后一个函数。 Likewise ->> inserts as the last argument. 同样, ->>作为最后一个参数插入。

user=> (macroexpand '(-> x (- 1)))
(- x 1)
user=> (macroexpand '(->> x (- 1)))
(- 1 x)

Two simple examples: 两个简单的例子:

user=> (-> 1 (- 1) (- 2)) 
-2
user=> (->> 1 (- 1) (- 2))
2

As for the first example, -2 == (- (- 1 1) 2) , and for the second 2 == (- 2 (-1 1)) 对于第一个示例, -2 == (- (- 1 1) 2) ,对于第二个示例2 == (- 2 (-1 1))

As a result, we get the same results for the unary functions. 结果,对于一元函数,我们得到相同的结果。

user=> (macroexpand '(-> 0 Math/sin Math/cos))
(. Math cos (clojure.core/-> 0 Math/sin))
user=> (macroexpand '(->> 0 Math/sin Math/cos))
(. Math cos (clojure.core/->> 0 Math/sin))

So, only ->> makes sense in the question. 因此,在问题中只有->>才有意义。

user=> (macroexpand '(->> a (+ 5) (let [a 5])))
(let* [a 5] (clojure.core/->> a (+ 5)))
user=> (macroexpand '(-> a (+ 5) (let [a 5])))

IllegalArgumentException let requires a vector for its binding in user:1  clojure.core/let (core.clj:4043)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM