这是我正在使用的代码,我创建记录然后尝试修改它们:
(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
的初始值将从文件中读入。
答案 0 :(得分:1)
问题“Can I create mutable state inside Clojure records?”与您的问题密切相关。关键点是
reset!
function operates on atoms。你得到了那个例外,因为reset!
正在弄清楚你给它一个它无法处理的参数,因为你给它的是不可变的。解决潜在问题的最佳方法是确定您是否需要记录或可变数据结构,并适当地更改数据表示。如果您继续使用记录(即这将是不可变的,您只需要关心在记录上设置一次值),您可以将更改移至:Index
和:Age
到{ {1}}功能。但是,您最好使用对不可变数据结构的引用并更改对更新的引用。