0

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

(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将从文件中读取。

4

1 回答 1

1

我可以在 Clojure 记录中创建可变状态吗? ”这个问题与您的问题密切相关。关键点是

  1. 记录通常是不可变的。
  2. reset!函数对原子进行操作

你得到这个异常reset!是因为你发现你给了它一个它无法处理的参数,而且你给它的参数是不可变的。解决潜在问题的最佳方法是确定您是否需要记录或可变数据结构,并适当地更改数据的表示。如果您确实继续使用记录(即,这将是不可变的,并且您只需关心在记录上设置一次值),您可以将更改移动到函数中:Index:Age移入make-record函数中。但是,您最好使用对不可变数据结构的引用并在更新时更改引用。

于 2013-04-06T00:20:39.077 回答