简体   繁体   English

遍历Clojure中的“ let”列表?

[英]Looping through a “let”-list in Clojure?

if I had an unknown number of argument that I want to bind to each other with a "let", like: 如果我想使用“ let”将彼此绑定的参数数量未知,例如:

let [a "hello" b 55 ]

If I bind let inside a function/macro or similar and I want to loop though the list, how would I do this? 如果我将let绑定在一个函数/宏或类似对象内,并且想遍历列表,我该怎么做?

Note that in the let there are 4 elements but I only want to loop through the "keys". 请注意,在let中有4个元素,但我只想遍历“键”。 An example of use could be to check if the value bound to a key is a number like b, which is 55 一个使用示例是检查键绑定的值是否是像b这样的数字,即55

Edit: As an example: Note that this following is very broken but it's merely intended to explain the problem: 编辑:作为一个示例:请注意,以下内容非常混乱,但仅用于解释问题:

(defn func [& arguments] 
 (let [ ~arguments] ((println "omg no way!") (for [x let-list] (number? x (println "roar") )))

input: (func [a "hello" b 55] 输入:(func [a“ hello” b 55]

So basically: I want to have a function that: 所以基本上:我想有一个功能,它:

  • binds the arguments to some form of list like: [ab] 将参数绑定到某种形式的列表,例如:[ab]
  • prints "omg no way!") - should not be part of a loop, should only print once in the function 打印“ omg no way!”)-不应该是循环的一部分,应该只在函数中打印一次
  • some kind of loop like a for loop that loops through the "let-list" so it would go: "a, is a number? no, is b number? yes, print "roar" 类似于for循环的某种循环,它循环遍历“ let-list”,因此它会运行:“ a,是数字吗?否,b是数字吗?是,打印“咆哮”

Output: omg no way roar 输出:omg没办法吼

Once again: I am wondering if there is a way to gain access to the keywords inside the let inside the function. 再次: 我想知道是否有一种方法可以访问函数内部的let内部的关键字。 As the for loop shows, I want to access each individual element and do things with the element. 如for循环所示,我想访问每个单独的元素并对该元素进行操作。 Had I used (for [x arguments] instead, it would've given: omg no way, roar roar (because b is tied to 55 so it's a number but 55 is also a number but there's no need to use 55 because 55 is already tied to b) 如果我使用了(对于[x参数],它会给出:omg绝不,吼吼(因为b绑定到55,所以它是一个数字,但55也是一个数字,但是不需要使用55,因为55是已经绑定到b)

here is an example of a macro that takes a list of alternating names and values, binds them in a let and then saves a map of the bindings that it just created by introducing a symbol called 'locals' that names a map of local-names to local-values. 这是一个宏的示例,该宏采用一个包含交替名称和值的列表,将它们绑定在let中,然后通过引入一个名为“ locals”的符号来命名刚创建的绑定的映射,该符号命名本地名称的映射到本地值。

(defmacro anaphoric-let [alternating-symbols-and-values & body]
  `(let [~@alternating-symbols-and-values
         names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values)))
         values#  ~(vec (flatten (partition 1 2 alternating-symbols-and-values)))
         ~'locals (zipmap names# values#)]
     ~@body))

any expressions called withing anaphoric-let will be able to use the values form the locals name. 使用with anaphoric-let调用的任何表达式都将能够使用locals名称的值。

user> (anaphoric-let [a 1 b 2 c 3 d 4] [a locals])
[1 {d 4, c 3, b 2, a 1}]

saving the values in a map after defining them with let and before the body is important to prevent multiple execution and the other sins of unhygienic macros. 在使用let定义之后 ,在主体之前将值保存在映射中对于防止多次执行以及不卫生的宏的其他缺点很重要。

this map can then be used to make decisions based on the locals: 然后可以使用此地图根据当地人做出决策:

user> (anaphoric-let [a 1 b 2 c 3 d 4 e "cat"] 
        (map (fn [[local val]] 
               (str local " is " (if (number? val) val "woof"))) 
              locals))
("e is woof" "d is 4" "c is 3" "b is 2" "a is 1")

or: 要么:

user> (anaphoric-let [a 1 b 2 c 3 d 4 e "cat"] 
        (println "omg no way!") 
        (dorun (for [x (vals locals)] 
                 (if (number? x) (println "roar")))))
omg no way!                                                                                                                                                    
roar                                                                                                                                                           
roar                                                                                                                                                           
roar                                                                                                                                                           
roar                                                                                                                                                           
nil

ps: anaphoic macros are any macro that introduces a name into the code it creates that did not exist in the code passed to it. ps:厌音宏是将名称引入其创建的代码中的任何宏,该名称在传递给它的代码中不存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM