我是 clojure 的新手,我见过这样写的匿名函数:
(fn [x] (* x x))
并且还喜欢:
#(* % %)
显然,第二种更简洁。有什么相关的区别吗?每个匿名函数都可以用任何一种风格表示吗?是更惯用的一种吗?
与这个问题相关,我无法确定如何转换(fn [x] [x x])
为后一种语法。我将不胜感激指向澄清这种情况的文档的指针。
我是 clojure 的新手,我见过这样写的匿名函数:
(fn [x] (* x x))
并且还喜欢:
#(* % %)
显然,第二种更简洁。有什么相关的区别吗?每个匿名函数都可以用任何一种风格表示吗?是更惯用的一种吗?
与这个问题相关,我无法确定如何转换(fn [x] [x x])
为后一种语法。我将不胜感激指向澄清这种情况的文档的指针。
最重要的区别是:
(fn ...)
可以嵌套,#()
不能(fn [x y] ..)
或类似名称更好地命名您的参数,而不是使用%
,%2
等%3
。(fn ...)
,例如(fn fib [n] (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))
(fn [...] ...)
由于#()
是阅读器宏而不是常规的 Clojure 形式,因此更容易进行代码生成/操作。#()
更简洁。但是,如果这是一个主要考虑因素,那么您的优先级可能是错误的:-)我个人的建议是:
(fn [...] ...)
大多数情况下更喜欢#()
非常短的内联函数,例如(map #(+ 2 %) (range 10))
(comp func1 func2)
或(partial func param1 param2)
等。另一个 SO 答案(Clojure 开发人员要避免的常见编程错误)提到#([% %])
扩展为fn [%] ([% %])
(注意括号),这会导致 ArityException。
您可以#(vector % %)
解决此限制。
从文档中,我认为这些是最相关的差异:
惯用的将用于非常短的一次性映射/过滤器 fns 等。
#() 表单不能嵌套。
另一件事是,如果您需要命名参数,fn 是一个更好的选择。对于#(),您将使用 %,或者对于多个参数,例如 %1、%2 等(还有 %&)。