在 functinoal 裡雖然想盡量保持 immutable ,但必要的時候還是需要有各種的方式儲存狀態,其中一個是使用 process。
與之前的 message 回覆相當類似,只差在我們啟動時可以帶入儲存的數值
defmodule Storage do
def init(value) do
spawn(fn -> wait_request(value) end)
end
defp wait_request(value) do
receive do
sender -> send(sender, value)
end
wait_request(value)
end
def read(pid) do
send(pid, self())
receive do
value -> value
end
end
end
讀取數值:
pid = Storage.init(100)
Storage.read(pid) #=> 100
因為事件變成兩種,可以將 wait_request
裡面的處理邏輯拿出來變成新的函式,這類的接收事件函式通常會被命名為 handle_***
像這次的 handle_event
defmodule Storage do
def init(value) do
spawn(fn -> wait_request(value) end)
end
defp wait_request(value) do
new_value =
receive do
event -> handle_event(event, value)
end
wait_request(new_value)
end
defp handle_event({:read, sender}, value) do
send(sender, value)
value
end
defp handle_event({:update, sender, update_fn}, value) do
new_value = then(value, update_fn)
send(sender, new_value)
new_value
end
def read(pid) do
send(pid, {:read, self()})
receive do
value -> value
end
end
def update(pid, update_fn) do
send(pid, {:update, self(), update_fn})
receive do
value -> value
end
end
end
執行看看
pid = Storage.init(3)
Storage.read(pid)
#=> 3
Storage.update(pid, fn x -> x + 3 end)
#=> 6
Storage.update(pid, fn x -> x + 3 end)
#=> 9
note: 雖然了解大概的原理會很好應用,但大多數情況不會自己寫,會使用下一篇介紹的 Agent