Clojure:从匿名函数返回向量

问题描述 投票:0回答:4

我编写了一个小的匿名函数,用于

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))

这个函数可以使用简化语法吗?如果是的话,怎么办?

谢谢。

clojure anonymous-function
4个回答
29
投票

你的问题是简单的语法试图将向量作为函数调用进行计算。

您可以插入一个“恒等”函数来使其工作,因为这只是一个简单的函数,它将返回向量不变:

#(identity [(keyword %) (.getObject resultset %)])

27
投票

您需要使用 vector 函数来执行此操作:

#(vector (keyword %) (.getObject resultset %))

附注还有地图、集合等功能


5
投票

是的,Clojure 确实应该支持 #[...] 构造,仅针对这种情况。

我建议以下作为最佳选择:

#(vector (keyword %) (.getObject resultset %))

0
投票

已经有很好的答案了。但没有答案解释发生了什么。

在 Clojure 中,您可以使用

#(...)
定义匿名函数文字。没有其他东西可以用来定义匿名函数文字。这发生在表单到达评估之前。这是所谓的读取器宏。读者真的必须看到这一点
#(
。当读者看到它时,立即将其替换为诸如
(fn [args] (...)
之类的东西。这是明确定义的here

这意味着,您只能将匿名函数文字用于具有完全相同的格式和括号的事物。如果您只想返回某些内容而不调用任何内容,则匿名函数文字不起作用。以下示例不能使用匿名函数文字编写,因为它们不需要括号。

(fn [x] x)
(fn [x] [x])
(fn [] 7)
(fn [] [7])

正如您在其他答案中看到的,有很好的解决方法,使您能够编写需要括号的内容。

一方面,编写用户宏会很有趣

#[...]
。但另一方面,正如您所看到的,在您的情况下,这并不是真正需要的。对于你的问题,有很好的解决方案。另请参阅有关该主题的此问题

请注意,在处理 EDN 数据时,主要有一个 解决方案。但这很可能无法回答您的问题,因为您可能不想使用 EDN 阅读器

© www.soinside.com 2019 - 2024. All rights reserved.