在Clojure中,有没有一种更优雅的方法可以将地图作为stdin中的成对列表输入?

在Clojure中,有没有一种更优雅的方法可以将地图作为stdin中的成对列表输入?,clojure,Clojure,目前,作为编码实践练习的一部分,我编写了以下代码,将一组空格分隔的对从stdin(作为可信源)读取到一个map中,其中先前定义了nbElevators: (让[电梯(进入{}(电梯#(做[(读)(读)])))))] 有更好的方法吗 我不喜欢#(do),但如果没有这一点,Clojure会不断地将反复解释为试图将向量作为函数调用,而不是将向量的外观视为表示返回向量的单一形式函数。这似乎很奇怪,因为表达式作为函数体是有效的(例如,(defn foo[]2),然而(重复52)没有,也没有,(重复5#(

目前,作为编码实践练习的一部分,我编写了以下代码,将一组空格分隔的对从stdin(作为可信源)读取到一个map中,其中先前定义了
nbElevators

(让[电梯(进入{}(电梯#(做[(读)(读)])))))]

有更好的方法吗

  • 我不喜欢
    #(do
    ),但如果没有这一点,Clojure会不断地将
    反复解释为试图将向量作为函数调用,而不是将向量的外观视为表示返回向量的单一形式函数。这似乎很奇怪,因为表达式作为函数体是有效的(例如,
    (defn foo[]2)
    ,然而
    (重复52)
    没有,也没有,
    (重复5#(2))
    -即使
    (重复5(fn[]2))
    有,这意味着读卡器宏中有一个漏洞。我在这里遗漏了什么语法吗

  • doall
    是否可以避免?是否有某种方法可以自动缓存或指定输入,以便在延迟计算序列时读取文件中的正确位置


对于第一点,请记住,在Clojure(和afaik,通常是lisps)中,
()
s有一组特殊的含义。除非宏在求值之前重新排列事物,
(f a)
意味着
f
将以
a
作为参数调用。这不是“漏洞”在宏中,我认为如果
#(2)
没有尝试调用
2
,那将更加令人惊讶。这将与函数调用工作的一致性背道而驰

您可以使用特殊表单查看
#()
扩展到的内容:

这说明了问题所在

就我个人而言,为了清晰起见,我会在那里使用
(fn[][(read)(read)])

当然,如果这有助于澄清的话,整个匿名函数也可以变成一个实际的独立函数


如果你想让
反复调用
,我会使用
vec
而不是
doall
,然后把惰性列表强制成一个向量。老实说,我还没有发现
doall
vec
没有处理的
蚂蚁

但在这种情况下,两者都不是必需的。
into
将严格强制
反复返回的集合。
并不是惰性的,因此无论如何都需要立即对其进行评估



我只是用一个
->
宏来分割它,这样它就不那么长了:

(let [elevators (->> (repeatedly nbElevators (fn [] [(read) (read)]))
                     (into {}))])
(fn[…)
位甚至可以将参数线程化,但我不认为这也可以读取,即使它会导致较短的行

这也可以通过使用@Amoloy提到的“构造函数”来重新编写。它采用var arg列表并将它们作为配对。这使您无需自己配对键/值:

(apply hash-map (repeatedly (* 2 nbElevators) read))

对于第一点,请记住,在Clojure(和afaik,通常是lisps)中,
()
s有一套特殊的含义。除非宏在求值之前重新排列事物,
(f a)
意味着
f
将以
a
作为参数调用。这不是“漏洞”在宏中,我认为如果
#(2)
没有尝试调用
2
,那将更加令人惊讶。这将与函数调用工作的一致性背道而驰

您可以使用特殊表单查看
#()
扩展到的内容:

这说明了问题所在

就我个人而言,为了清晰起见,我会在那里使用
(fn[][(read)(read)])

当然,如果这有助于澄清的话,整个匿名函数也可以变成一个实际的独立函数


如果你想让
反复调用
,我会使用
vec
而不是
doall
,然后把惰性列表强制成一个向量。老实说,我还没有发现
doall
vec
没有处理的
蚂蚁

但在这种情况下,两者都不是必需的。
into
将严格强制
反复返回的集合。
并不是惰性的,因此无论如何都需要立即对其进行评估



我只是用一个
->
宏来分割它,这样它就不那么长了:

(let [elevators (->> (repeatedly nbElevators (fn [] [(read) (read)]))
                     (into {}))])
(fn[…)
位甚至可以将参数线程化,但我不认为这也可以读取,即使它会导致较短的行

这也可以通过使用@Amoloy提到的“构造函数”来重新编写。它采用var arg列表并将它们作为配对。这使您无需自己配对键/值:

(apply hash-map (repeatedly (* 2 nbElevators) read))

谢谢!我有点误解了,因为我认为
#(x)
相当于
(fn[]x)
而不是
(fn[]x))
@MarkGreen仅供参考,试着评估
(引号#(向量1))
。你可以看到
#()
的扩展。谢谢!我有点误解,因为我认为
#(x)
相当于
(fn)[]x)
不是
(fn[](x))
@MarkGreen仅供参考,请尝试评估
(矢量1))
。您可以看到
#()
展开的内容。