Clojure: Обновление значения поля записи

#clojure

Вопрос:

Я определил запись для хранения сведений о пользователе и сведений об адресе.

 (defrecord User [id name address])

(defrecord Address [id location street city state])

(def usr (User. 1 "Abc"
           (Address. 1 "Location 1" "Street" "NY" "US")))
 

Я обновил «имя» до «BCD», используя приведенный ниже код

 (assoc usr :name "BCD")
 

Выход:

 #async_tea_party.core.User{:id 1, :name "BCD", :address #async_tea_party.core.Address{:id 1, :location "Location 1", :street "Street", :city "NY", :state "US"}}
 

(usr)

выход:

 #async_tea_party.core.User{:id 1, :name "Abc", :address #async_tea_party.core.Address{:id 1, :location "Location 1", :street "Street", :city "NY", :state "US"}}
 

Новое значение name поля не обновилось, и оно по-прежнему показывает старое значение.

Как я могу постоянно обновлять поле «имя» в записи «Пользователь»?

Ответ №1:

(def usr (User...)) это своего рода непреложно. Вы не можете это изменить. Когда вы это делаете (assoc usr :name "BCD") , вы этого не меняете. Вы создаете новый. Для того, чтобы делать то, что вы хотите, вам нужен атом.

 (def usr (atom (User. 1 "Abc"
           (Address. 1 "Location 1" "Street" "NY" "US"))))

(:name @usr) ;; "Abc"
(swap! usr assoc :name "BCD")
(:name @usr) ;; "BCD"
 

Комментарии:

1. @user1702169 Эта работа. Но, скорее всего, вам нужно структурировать свою программу, чтобы не полагаться на atom, и передавать новую запись там, где она вам нужна напрямую.

Ответ №2:

Это называется неизменяемостью и является одной из главных причин, по которой мне так нравится clojure.

Чтобы понять причины, по которым такое поведение так полезно, чтение ценностей и состояния действительно помогло мне