我正在做一些关于clojure(初学者)的研究,我发现了一个例子,事情是我无法理解“(str%2%1)”中“%2”和“%1”的值是什么。完整示例如下:
(defn my-reverse [s]
(let [lst (list)]
(reduce #(str %2 %1)
(mapcat #(conj lst %1) s))))
我理解%2引用了第二个参数,但我只在“#(str%2%1)”之后看到一个参数值,它是mapcat表达式,应该是%1。
感谢您的帮助。希望我已经清楚了。
答案 0 :(得分:3)
#(str %2 %1)
是reduce
的第一个参数:
(减少f coll)
f应该是2个参数的函数...返回应用的结果 f到coll中的前2项,然后将f应用于该结果和 第3项等等。
因此f
的一个参数是要处理的当前值(集合coll
中的当前项),另一个是到目前为止的累积结果。
在这种情况下,(mapcat #(conj lst %1) s)
的结果是集合。在第一次调用#(str %2 %1)
时,参数%1
和%2
将是该集合中的前两个值。下次将使用该结果和集合中的第三个值调用它。因此,构建一个包含(mapcat #(conj lst %1) s)
生成的所有值的字符串。
答案 1 :(得分:3)
符号#(...)
是创建匿名函数的简写。
创建匿名函数的更长方法是lambda表达式,由clojure中的符号fn
引入:
(fn [arg1 arg2]
(do-something-with arg1 arg2))
简写允许您省略fn
和参数列表,而不是使用默认参数名称:
#(do-something-with %1 %2)
所以,你的例子扩展了:
#(str %2 %1)
扩展为
(fn [thing1 thing2]
(str thing2 thing1))
和
#(conj lst %1)
扩展为
(fn [thing]
(conj lst thing))