我编写了一个小的匿名函数,用于
map
调用。该函数返回一个向量,其中包含 SQL 结果集查询中的列名称和列值。
这是函数(输入是列名称):
(fn [name] [(keyword name) (.getObject resultset name)])
这工作正常,但是当我尝试使用匿名函数的“简化”版本时,我收到错误:
#([(keyword %) (.getObject resultset %)])
java.lang.IllegalArgumentException: Wrong number of args (0) passed to: PersistentVector
这是
map
电话:
(into {} (map (fn [name] [(keyword name) (.getObject resultset name)]) column-names))
这个函数可以使用简化语法吗?如果是的话,怎么办?
谢谢。
你的问题是简单的语法试图将向量作为函数调用进行计算。
您可以插入一个“恒等”函数来使其工作,因为这只是一个简单的函数,它将返回向量不变:
#(identity [(keyword %) (.getObject resultset %)])
您需要使用 vector 函数来执行此操作:
#(vector (keyword %) (.getObject resultset %))
附注还有地图、集合等功能
是的,Clojure 确实应该支持 #[...] 构造,仅针对这种情况。
我建议以下作为最佳选择:
#(vector (keyword %) (.getObject resultset %))
已经有很好的答案了。但没有答案解释发生了什么。
在 Clojure 中,您可以使用
#(...)
定义匿名函数文字。没有其他东西可以用来定义匿名函数文字。这发生在表单到达评估之前。这是所谓的读取器宏。读者真的必须看到这一点#(
。当读者看到它时,立即将其替换为诸如(fn [args] (...)
之类的东西。这是明确定义的here。
这意味着,您只能将匿名函数文字用于具有完全相同的格式和括号的事物。如果您只想返回某些内容而不调用任何内容,则匿名函数文字不起作用。以下示例不能使用匿名函数文字编写,因为它们不需要括号。
(fn [x] x)
(fn [x] [x])
(fn [] 7)
(fn [] [7])
正如您在其他答案中看到的,有很好的解决方法,使您能够编写需要括号的内容。
一方面,编写用户宏会很有趣
#[...]
。但另一方面,正如您所看到的,在您的情况下,这并不是真正需要的。对于你的问题,有很好的解决方案。另请参阅有关该主题的此问题。