Kernel.get_in如何将函数用作键?

时间:2016-09-24 18:34:08

标签: elixir

我无法弄清楚它是如何工作的。以下是Elixir文档的示例代码,以及我们关于它们如何工作的思考过程。如果出现问题,请告诉我。

# Code example from Elixir docs
users = [%{name: "john", age: 27}, %{name: "meg", age: 23}]
all = fn(:get, data, next) do
    Enum.map(data, next) 
end
get_in(users, [all, :age])
#=> [27, 23]
  1. users与包含两张地图的列表匹配。
  2. all与以:get, data, next为参数并执行Enum.map(data, next)的函数匹配。
  3. Kernal.get_in(users, [all, :age])被召唤。
  4. 由于其中一个键all是一个函数,因此将其调用为all(:get, users, next)
  5. Enum.map遍历users的每个元素并在其上调用next,返回一个列表。
  6. 列表中每个用户的:age键的值将作为列表返回。
  7. 这些是基于此分析的问题:

    1. 这个函数是什么next?它从未被定义或提供,但是如何报告没有错误?
    2. 总结一下,当使用函数(在此示例中为get_in)作为键调用all时,它会返回键的值(在此示例中为:age })从该函数的结果?
    3. 如果我在2.中的猜测是正确的,那么当该函数的结果不是字典类型且没有键值对时会发生什么?它会引起错误吗?

1 个答案:

答案 0 :(得分:1)

有两个完美的来源可以从中检索信息。第一个是Elixir Docs,即Kernel#get_in/2的状态:

  

从嵌套结构中获取值。

     

[...]

     

如果一个键是一个函数,那么将调用该函数传递三个参数,即操作(:get),要访问的数据和下一个要调用的函数。

最终来源是Elixir源代码,我们可以在其中看到Kernel#get_in/2 in our particular case的确切实现。

那就是说,next在这里扮演acc的角色,将get_in传递给尾递归,直到列表的尾部为空。

问题2在文档中得到了完美的回答。

问题3的答案是:another Kernel#get_in/2将在上一步中匹配,递归将开始显示。