Macros Clojure';s->;及->&燃气轮机;宏
Clojure的Macros Clojure';s->;及->&燃气轮机;宏,macros,clojure,operators,Macros,Clojure,Operators,Clojure的->宏从上一个参数执行窗体线程,而从第一个参数执行->窗体线程 user=> (->> a (+ 5) (let [a 5])) 10 然而,当我使用交换的操作时,我得到了一个异常 user=> (-> a (let [a 5]) (+ 5)) CompilerException java.lang.IllegalArgumentException: let requires a vector for its binding in user:1,
->
宏从上一个参数执行窗体线程,而从第一个参数执行->
窗体线程
user=> (->> a (+ 5) (let [a 5]))
10
然而,当我使用交换的操作时,我得到了一个异常
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)
此外,我希望这两个操作将得到相同的结果,但事实并非如此
user=> (-> 0 (Math/cos) (Math/sin))
0.8414709848078965
user=> (->> 0 (Math/sin) (Math/cos))
1.0
怎么了?
->
和->
宏如何工作?宏将参数作为给定函数的第一个参数插入,而不是将参数提供给最后一个函数。
同样地,->
插入作为最后一个参数
user=> (macroexpand '(-> x (- 1)))
(- x 1)
user=> (macroexpand '(->> x (- 1)))
(- 1 x)
两个简单的例子:
user=> (-> 1 (- 1) (- 2))
-2
user=> (->> 1 (- 1) (- 2))
2
对于第一个示例,-2==(-11)2
,对于第二个示例,2==(-2(-11))
因此,对于一元函数,我们得到了相同的结果
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))
因此,只有->
在这个问题上有意义
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)
->
宏将参数作为给定函数的第一个参数插入,而不是将参数提供给最后一个函数。
同样地,->
插入作为最后一个参数
user=> (macroexpand '(-> x (- 1)))
(- x 1)
user=> (macroexpand '(->> x (- 1)))
(- 1 x)
两个简单的例子:
user=> (-> 1 (- 1) (- 2))
-2
user=> (->> 1 (- 1) (- 2))
2
对于第一个示例,-2==(-11)2
,对于第二个示例,2==(-2(-11))
因此,对于一元函数,我们得到了相同的结果
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))
因此,只有->
在这个问题上有意义
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)
... 而且
->
和->
都从左到右应用它们的参数形式,因此(>0(Math/cos)(Math/sin))
与(>0(Math/cos)(Math/sin))
相同,而不是(>(Math/sin)(Math/cos))
。。。而且->
和->
都从左到右应用它们的参数形式,因此(>0(Math/cos)(Math/sin))
与(>0(Math/cos)(Math/sin))
相同,而不是(>(Math/sin)(Math/cos))