在 Elixir 中制作一个带有闭包的计数器

问题描述 投票:0回答:1

我正在学习 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 处理这种纯粹假设情况的方法是什么?

javascript elixir closures immutability
1个回答
0
投票

主要问题似乎是

count
在 Elixir 中是不可变的。

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
© www.soinside.com 2019 - 2024. All rights reserved.