轨道
/
Elixir
Elixir
/
练习
/
社区花园
社区花园

社区花园

学习练习

简介

Agent

Agent模块提供了一层抽象,用于创建进程和_接收-发送循环_。从现在起,我们把使用Agent模块启动的进程称为_“代理进程”_。_代理进程_可以用来表示一个集中式共享状态。

要启动一个_代理进程_,Agent提供了start/2函数。调用start启动_代理进程_时,传入的函数会返回该进程的初始状态:

# Start an agent process with an initial value of an empty list
{:ok, agent_pid} = Agent.start(fn -> [] end)

就像Map或List一样,Agent提供了许多用于操作_代理进程_的函数。

通常的做法是把所有与Agent相关的功能组织并封装到一个模块中,用于所建模的领域。

说明

你的社区协会请你实现一个简单的登记应用,用来管理社区花园的地块登记。Plot 结构体已经为你准备好了。

1. 开启花园

实现CommunityGarden.start/1函数,它应接收一个可选的关键字列表,其中的选项会继续传给 agent 进程。花园的初始状态应被初始化为一个空的地块集合。它应返回一个包含花园 pid 的:ok元组。

{:ok, pid} = CommunityGarden.start()
# => {:ok, #PID<0.112.0>}

2. 列出登记信息

实现CommunityGarden.list_registrations/1函数。它应接收社区花园的pid。它应返回一个列表,包含所有已登记的地块。

CommunityGarden.list_registrations(pid)
# => []

目前我们还没有添加登记地块的功能,所以这个列表应该是空的

3. 把地块登记到某个人的名下

实现CommunityGarden.register/2函数。它应接收社区花园的pid和一个用于登记地块的姓名。成功时,它应返回Plot结构体,其中包含该地块的 id 和登记人。

id 应该是递增且唯一的。你可以在 agent 的状态中保存一个 id 计数器。

CommunityGarden.register(pid, "Emma Balan")
# => %Plot{plot_id: 1, registered_to: "Emma Balan"}
CommunityGarden.list_registrations(pid)
# => [%Plot{plot_id: 1, registered_to: "Emma Balan"}]

4. 释放地块

实现CommunityGarden.release/2函数。它应接收待释放地块的pid和id。成功时应返回:ok。地块被释放后,它的 id 不会被重新使用,id 只用作唯一标识符。

CommunityGarden.release(pid, 1)
# => :ok
CommunityGarden.list_registrations(pid)
# => []

5. 获取已登记的地块

实现CommunityGarden.get_registration/2函数。它应接收待检查地块的pid和id。如果该地块已登记,就返回它;如果未登记,则返回:not_found。

CommunityGarden.get_registration(pid, 1)
# => %Plot{plot_id: 1, registered_to: "Emma Balan"}
CommunityGarden.get_registration(pid, 7)
# => {:not_found, "plot is unregistered"}
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Elixir Exercism

准备好开始 社区花园 了吗?

注册 Exercism,借助 58 个概念168 个练习 和真人导师指导,学习并掌握 Elixir,全部免费。