我是Clojure初学者,想要了解->
宏的作用。
以下代码可以正常工作:
(-> '(1 2 3) reverse)
但是这段代码甚至无法编译,我不知道如何处理错误信息:
user=> (-> '(1 2 3) (fn [x] (reverse x)))
编译异常:java.lang.IllegalArgumentException: 参数声明应为向量,编译:(NO_SOURCE_PATH:1:1)。
如何解决这个问题?
我是Clojure初学者,想要了解->
宏的作用。
以下代码可以正常工作:
(-> '(1 2 3) reverse)
user=> (-> '(1 2 3) (fn [x] (reverse x)))
当遇到意外情况时,我经常使用macroexpand
及其相关工具。如果在此处使用它们,那么问题就会变得非常明显。
user=> (macroexpand-1 '(-> '(1 2 3) (fn [x] (reverse x))))
(fn (quote (1 2 3)) [x] (reverse x))
我认为看到这个很明显的是,(quote (1 2 3)
不应该是fn
的第一个参数。
我们还可以看到,丑陋的双括号方法可以解决这个问题:
user=> (macroexpand-1 '(-> '(1 2 3) ((fn [x] (reverse x)))))
((fn [x] (reverse x)) (quote (1 2 3)))
顺便提一句,这可能会让你困扰: 在这里你必须使用macroexpand-1
来获得结果。 如果你使用macroexpand
或clojure.walk/macroexpand-all
,它会在第一次展开后崩溃(抛出异常),因为fn
本身是一个宏,在第一次展开后,它被用错误的语法调用。