当我尝试修改此记录时,为什么会出现一个错误,说它是一个懒惰的序列?

时间:2013-01-04 04:39:37

标签: clojure lazy-evaluation

这是我正在使用的代码,我创建记录然后尝试修改它们:

(defrecord Record [Name Age Index ClassIndex])

(defn read-csv [fname count]
  (with-open [file (io/reader fname)]
    (doall (map #(str/split % #",") ;; doesn't work with commas in text fields
             (take count (line-seq file))))))

(defn make-record [idxs types row]
  (apply ->Record
    (map (fn [idx t]
           (let [value (nth row idx)]
             (case t
               :string value
               :int (Integer/parseInt value)
               :long (Long/parseLong value))))
             idxs types)))

(def records
  (doall (map (partial make-record
                [0 1 2 3]
                [:string :int :long :int])
           (read-csv "C:/Users/user/Documents/URECA/hi/lib/test.csv" 1))))

(reset! records
  (map #(assoc % :ClassIndex
         (+ (:Age %) (:Index %)) :Age (+ 1 :Age %))
    @records))

当我运行此代码时,我得到了这个例外:

ClassCastException clojure.lang.LazySeq cannot be cast to
clojure.lang.IDeref  clojure.core/deref (core.clj:2080)

为什么我收到此错误?

更新以回复评论:

我有一张记录图,我想更新这些记录。课程:Index将由:Age + :Index的值决定。但是,:Age:Index的初始值将从文件中读入。

1 个答案:

答案 0 :(得分:1)

问题“Can I create mutable state inside Clojure records?”与您的问题密切相关。关键点是

  1. 记录通常是不可变的。
  2. The reset! function operates on atoms
  3. 你得到了那个例外,因为reset!正在弄清楚你给它一个它无法处理的参数,因为你给它的是不可变的。解决潜在问题的最佳方法是确定您是否需要记录或可变数据结构,并适当地更改数据表示。如果您继续使用记录(即这将是不可变的,您只需要关心在记录上设置一次值),您可以将更改移至:Index:Age到{ {1}}功能。但是,您最好使用对不可变数据结构的引用并更改对更新的引用。