你可以用同样的想法在有和没有可变状态的情况下做到这一点。您运行一个函数,该函数采用地址的原始状态和您想要添加的状态,然后返回一组新地址,包括新状态。当然,它不会破坏原件,因为有人可能会看到它。
定义基本地址簿:
user> (def addresses [])
#'user/addresses
定义一个包含新值的新地址簿:
user> (def book-with-dirk
(conj addresses {:name "dirk" :address "123 internet st."}))
#'user/book-with-dirk
user> book-with-dirk
[{:name "dirk", :address "123 internet st."}]
这不会更改基本地址簿,而是创建一个新的地址簿,将原始地址簿与 dirk 的新值有效地结合起来。所以地址还是一样的。
user> addresses
[]
您还可以使用托管可变状态以功能方式维护名为地址的身份的内容。如果有人在看,地址原子中的原始值仍然存在(否则为 GCd)
user> (def addresses (atom []))
#'user/addresses
制作一个新的地址簿,就像上面一样包含 dirk,除了这个地址簿还在地址标识中创建下一个值:
user> (def book-with-dirk (swap! addresses conj {:name "dirk" :address "123 internet st."}))
#'user/book-with-dirk
现在 book-with-dirk 是一个包含带有 dirk 的书的值。
user> book-with-dirk
[{:name "dirk", :address "123 internet st."}]
并且地址也包含新值。
user> @addresses
[{:name "dirk", :address "123 internet st."}]
如果我再添加 Joe,book-with-dirk 将不会改变
user> (swap! addresses conj {:name "Joe" :address "321 internet st."})
[{:name "dirk", :address "123 internet st."}
{:name "Joe", :address "321 internet st."}]
user> book-with-dirk
[{:name "dirk", :address "123 internet st."}]