类似于Clojure的方法在循环中拥有数据结构

时间:2016-05-14 19:34:06

标签: clojure

我觉得有点难以理解这一点。比方说,在Python中,如果我想要一个基于用户输入在循环中修改的列表,我会有这样的事情:

def do_something():
    x = []
    while(true):
        input = raw_input('> ')
        x.append(input)
        print('You have inputted:')
        for entry in x:
            print(entry)

我真的不确定类似Clojure的方式是什么类似的。到目前为止,我有这样的事情:

(defn -main
  [arg]
    (print "> ")
    (flush)
    (let [input (read-string (read-line))]
      ; Append a vector?
      (println "You have inputted:")
      ; Print the contents of vector?
      (recur <the vector?>)))

基本上,我追加向量并将向量作为下一个递归循环的参数。这是正确的做法吗?我甚至不确定我会怎么做,但我就是这样做的。我会在哪里“存储”矢量?有什么帮助吗?

2 个答案:

答案 0 :(得分:4)

你在python中做的是你正在改变向量x。这不是在clojure中做事的标准方式。 clojure中的数据结构默认是不可变的。因此,您必须每次都创建新的向量并将其传递给下一次迭代。

(defn -main
  [arg]    
  (loop [vec []]
       (let [input (read-string (read-line))]
         (let [next-vec (conj vec input)]
           (println (str "You have inputted:" next-vec))
           (recur next-vec)))))

答案 1 :(得分:0)

以下是其工作原理的示例:

(ns clj.core
  (:use tupelo.core))

(defn loopy []
;        "var"   "init val"
  (loop [ idx      0
          result   "" ]
    (if (< idx 5)
      (recur (inc idx)              ; next value of idx
             (str result " " idx))  ; next value of result
      result)))
(spyx (loopy))


(defn -main [] )

和输出:

> lein run
(loopy) => " 0 1 2 3 4"

因此loop表达式定义了循环&#34;变量&#34;和他们的初始值。 recur表达式为循环的下一次迭代设置每个变量的值。

由于您正在累积用户输入,因此您可能希望使用字符串而不是向量。或者,你可以改变它:

(defn loopy []
;      "var"   "init val"
  (loop [idx      0
         result   [] ]
    (if (< idx 5)
      (recur (inc   idx)             ; next value of idx
             (glue  result [idx] ))  ; next value of result
      result)))
(spyx (loopy))


> lein run (loopy) => [0 1 2 3 4]

将项目累积到矢量中。请注意,您也可以在recur表达式中使用此表达式,而不是glue

(append result idx)

其中函数appendgluespyx都是found in the Tupelo library。享受!