我无法理解'&'运算符在以下上下文中。
@doc "Marks a task as executed"
def put_task(task, project) do
item = {task, project}
Agent.update(__MODULE__, &MapSet.put(&1, item))
end
在这种情况下,似乎'& 1'是指地图对象本身,但我很好奇这是如何工作的。它是作为一个参数传递给我自己在文档中查看这个,但无法确定这是否正是发生的事情。如果有人能够帮助我理解究竟发生了什么以及& 1引用了什么以及它是否引用了MapSet,我将不胜感激。
答案 0 :(得分:21)
&1
是函数的第一个参数。整个&
符号基本上是表达匿名函数的另一种方式 - Enum
或Agent
对此没有任何特定之处。让我们举个例子:
fn (x, y, z) -> (x + z) * y end
这是一个匿名函数,它接受3个参数,添加第一个和第三个参数,并将结果乘以第二个参数。使用&
表示法:
&((&1 + &3) * &2)
将&1
,&2
和&3
视为参数所在的表达式中的占位符。所以当你这样做时
Agent.update(__MODULE__, &MapSet.put(&1, item))
您使用一个参数函数调用Agent.update
,该函数使用该参数和项调用MapSet.put
- 无论是什么。它相当于:
Agent.update(__MODULE__, fn x -> MapSet.put(x, item) end)
答案 1 :(得分:5)
让我们考虑一个更简单的例子,
Enum.map [1, 2, 3, 4], &(&1 * 2)
Enum.map [1, 2, 3, 5], fn x -> x * 2 end // Exactly like above
到Enum.map
我们基本上传递了一个列表和一个匿名函数。 Enum.map
期望匿名函数至少有一个参数(没有脑子,它将列表的每个元素传递给匿名函数)。所以这里&1
这是匿名函数的第一个参数,它将在调用我们的匿名函数时由Enum.map
设置。 Enum.map
遍历列表,每次使用列表中的不同元素调用我们的匿名函数。
虽然我不知道Agent.update
的实现,但就我看到它的作用而言,Agent.update
正在调用代理_MODULE_
并在此应用函数Map.Set接收代理的旧状态,并设置代理的新状态。换句话说,你可以说&1
是代理的旧状态
答案 2 :(得分:5)
如果有人能帮助我理解究竟发生了什么以及& 1引用了什么以及它是否引用了MapSet,我将不胜感激。
Agent.update/3
使用当前状态调用给定函数,并将返回值存储为新状态。由于&MapSet.put(&1, item)
与fn x -> MapSet.put(x, item) end
相同,因此x
成为旧状态,MapSet
返回的新MapSet.put/2
成为代理的新状态。
要使此代码正常运行,必须使用Agent.start
调用Agent.start_link
或name: __MODULE__
以及返回{:ok, map_set}
map_set
的函数MapSet
代码中的某个地方。