elixir - 21 agent
访问量: 1503
参考:https://elixir-lang.org/getting-started/mix-otp/agent.html
elixir 是一门 immutable 的语言, 如何在各个process之间共享数据就是问题。
agent可以用来实现共享state
iex> {:ok, agent} = Agent.start_link fn -> [] end {:ok, #PID<0.57.0>} iex> Agent.update(agent, fn list -> ["eggs" | list] end) :ok iex> Agent.get(agent, fn list -> list end) ["eggs"] iex> Agent.stop(agent) :ok 上面的代码,实现了使用Agent对 agent中的[]进行设置和修改。
创建一个新文件:
1. lib/kv/bucket.ex defmodule KV.Bucket do use Agent def start_link(_opts) do Agent.start_link(fn -> %{} end) end def get(bucket, key) do Agent.get(bucket, &Map.get(&1, key)) end # 这里的 &Map.put 。 就是capture def put(bucket, key, value) do Agent.update(bucket, &Map.put(&1, key, value)) end end 2. test/kv/bucket_test.exs defmodule KVTest do use ExUnit.Case doctest KV test "greets the world" do assert KV.hello() == :world end end
capture: 上面的
Agent.update(bucket, &Map.put(&1, key, value))
也可以写成:
Agent.update(bucket, fn(x) -> Map.get(x, key) end )
还可以在单元测试中使用 setup
defmodule KV.BucketTest do use ExUnit.Case, async: true setup do # 这里的 my_name 已经成为了一个变量,下面这个 keyword list 是个返回值 %{my_name: "jim"} end test "stores values by key" do {:ok, bucket} = KV.Bucket.start_link([]) assert KV.Bucket.get(bucket, "milk") == nil KV.Bucket.put(bucket, "milk", 3) assert KV.Bucket.get(bucket, "milk") == 3 end # 下面, %{my_name: my_name} 中,先声明了变量my_name, 并且把setup中的最后一行,为my_name赋值 , # 这里严格的说,是把%{} 合并到 test..do 的 context中。 test "shows how to use setup ", %{my_name: my_name} do IO.puts "my_name: #{my_name}" assert my_name == "jim" end end