这是我之前的问题的后续。
我从阅读Let Over Lambda中想出了一个奇怪的对象方案,并且认为没有协议的优势,但想获得意见。我只是在探索使用高阶函数和封装。
(defn new-person
"Construct a new Person object and return a Map of accessor methods."
[init-first-name init-last-name init-age]
(let [first-name (ref init-first-name)
last-name (ref init-last-name)
age (ref init-age)]
{:get-first-name #(@first-name)
:set-first-name #(dosync (ref-set first-name %1))
:get-last-name #(@last-name)
:set-last-name #(dosync (ref-set last-name %1))
:get-age #(@age)
:set-age #(dosync (ref-set age %1))}))
我可以像这样使用对象:
(def fred (new-person "fred" "flintstone" 42))
并以这种方式检索访问器方法:
(fred :get-age)
但我不知道如何调用访问器。
创建的对象是线程安全的,因为“实例”变量的所有突变都发生在 STM 中。
更新:新的和改进的版本:
(defn new-person
"Construct a new Person object and return a Map of accessor methods."
[init-first-name init-last-name init-age]
(let [first-name (ref init-first-name)
last-name (ref init-last-name)
age (ref init-age)]
{:first-name
(fn
([] @first-name)
([val] (dosync (ref-set first-name val))))
:last-name
(fn
([] @last-name)
([val] (dosync (ref-set last-name val))))
:age
(fn
([] @age)
([val] (dosync (ref-set age val))))}))