我正在学习 Elixir,刚刚学习到关于闭包的部分。当一种语言有闭包时,我通常做的第一件事就是尝试制作闭包算法。在 JavaScript 中,它看起来像这样:
let counter = function() {
let count = 0;
return function() {
count += 1;
return count;
};
}();
然后,每次调用
counter
时,都会按顺序返回一个新数字。
counter(); // returns 1
counter(); // returns 2
counter(); // returns 3
counter(); // etc.
可以用 Elixir 来做这个吗?主要问题似乎是
count
在 Elixir 中是不可变的。我可以将其设为单元素列表,但这听起来像是一个坏主意™。 Elixir 处理这种纯粹假设情况的方法是什么?
主要问题似乎是
在 Elixir 中是不可变的。count
iex(1)> count = 1
1
iex(2)> IO.puts count
1
:ok
iex(3)> count = 2
2
iex(4)> IO.puts count
2
:ok
可以用 Elixir 来做这个吗?
在 Elixir/Erlang 中,您可以使用称为
gen_server
的东西来跟踪状态:
defmodule Counter do
use GenServer
#Client interface:
def start_counter(starting_count) do
GenServer.start_link(__MODULE__, starting_count)
end
def get_count(pid) do
GenServer.call(pid, :increment)
end
# Callbacks
@impl true
def init(starting_count) do
{:ok, starting_count}
end
@impl true
def handle_call(:increment, _from, current_count) do
{:reply, current_count, current_count+1}
end
end
在 iex 中:
iex(1)> c("a.ex")
[Counter]
iex(2)> {:ok, pid} = Counter.start_counter(1)
{:ok, #PID<0.119.0>}
iex(3)> Counter.get_count(pid)
1
iex(4)> Counter.get_count(pid)
2
iex(5)> Counter.get_count(pid)
3
iex(6)> Counter.get_count(pid)
4