How does the '&' operator work?

有些话、适合烂在心里 提交于 2019-12-23 15:00:17

问题


I am having trouble understand the '&' operator in the following context.

  @doc "Marks a task as executed"
  def put_task(task, project) do
    item = {task, project}
    Agent.update(__MODULE__, &MapSet.put(&1, item))
  end

It seems that in this case the '&1' is referring to the map object itself, but I am curious as to how this works. Is it passing itself in as an argument I looked into this in the docs but couldn't find out if this was exactly what was going on. I would be grateful if somebody could help me understand what is exactly going on and what &1 refers to and if it refers to the MapSet how is this possible.


回答1:


I would be grateful if somebody could help me understand what is exactly going on and what &1 refers to and if it refers to the MapSet how is this possible.

Agent.update/3 calls the given function with the current state, and stores the returned value as the new state. Since &MapSet.put(&1, item) is the same as fn x -> MapSet.put(x, item) end, x here becomes the old state, and the new MapSet returned by MapSet.put/2 becomes the new state of the agent.

For this code to function, there must be a call to Agent.start or Agent.start_link with name: __MODULE__ and a function that returns {:ok, map_set} where map_set is any MapSet somewhere in the code.




回答2:


The &1 is the first argument of the function. The whole & notation is basically an alternative way to express anonymous functions - there's nothing specific to Enum or Agent about it. Let's take this example:

fn (x, y, z) -> (x + z) * y end

This is an anonymous function that takes 3 arguments, adds the first and third one and multiplies the result by the second one. With the & notation:

&((&1 + &3) * &2)

Think of the &1, &2 and &3 as placeholders in an expression where the arguments will go. So when you do

Agent.update(__MODULE__, &MapSet.put(&1, item))

You're calling Agent.update with a one-argument function that calls MapSet.put with that argument and item - whatever that is. It's equivalent to:

Agent.update(__MODULE__, fn x -> MapSet.put(x, item) end)



回答3:


Lets consider a more simple example,

Enum.map [1, 2, 3, 4], &(&1 * 2)

Enum.map [1, 2, 3, 5], fn x -> x * 2 end // Exactly like above

To Enum.map we are basically passing a list and an anonymous function. Enum.map expects the anonymous function to have atleast one argument(no brainer, it passes each element of the list to anonymous function). So here &1 which is the first argument of the anonymous function which will be set by Enum.map when it calls our anonymous function. Enum.map loops through the list calling our anonymous function each time with a different element of our list.

Though I do not know the implementation of the Agent.update, but as far as I see what its doing is, Agent.update is calling on the agent which is _MODULE_ and on this applying function Map.Set which receives the old state of the agent, and sets new state of the agent. In other words you could say &1 is the old state of the agent



来源:https://stackoverflow.com/questions/37982351/how-does-the-operator-work

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!