我有任意数量的列表,我想使用 for 宏来处理它们。我想创建一个传递向量作为绑定的函数,因为列表的数量各不相同。
如果我对绑定进行硬编码,它会按我的预期工作:
=> (def list1 '("pink" "green"))
=> (def list2 '("dog" "cat"))
=> (for [A list1 B list2] (str A "-" B))
("pink-dog" "pink-cat" "green-dog" "green-cat")
当我尝试单独创建一个向量并将其用作绑定时,我遇到了问题。这里我手动创建绑定向量:
=> (def testvector (vec (list 'A list1 'B list2)))
这看起来不错:
=> testvector
[A ("pink" "green") B ("dog" "cat")]
=> (class testvector)
clojure.lang.PersistentVector
然而,
=> (for testvector (str A "-" B))
#<CompilerException java.lang.IllegalArgumentException: for requires a vector for its binding (NO_SOURCE_FILE:36)>
我不明白为什么 testvector 在用作 for 中的绑定时不被视为向量。抓住救命稻草,我将 testvector 放在方括号中,这使 for 宏满意(它看到一个向量),但现在我有一个包含一个元素的向量(即向量内的向量),但这不起作用,因为绑定需要是名称和集合对。
=> (for [testvector] (str A "-" B))
#<CompilerException java.lang.IllegalArgumentException: for requires an even number of forms in binding vector (NO_SOURCE_FILE:37)>
任何有关如何动态传递向量作为 for 的绑定的建议将不胜感激。
关键是for是一个宏。在宏展开时,testvector是一个符号。它将在评估时评估为向量,但从for macro.
user=> (defmacro tst [v] (vector? v))
#'user/tst
user=> (tst testvector)
false
user=> (vector? testvector)
true
user=> (defmacro tst2 [v] `(vector? ~v))
#'user/tst2
user=> (tst2 testvector)
true
如果您检查源for宏(在 core.clj 中),你会看到for使用不带引号的vector?打电话,就像tst在上面的例子中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)