2016-09-24 47 views
0

我無法弄清楚它是如何工作的。以下是來自Elixir文檔的示例代碼,以及我如何工作的思考過程。請讓我知道是否有什麼問題。Kernel.get_in如何使用函數作爲關鍵字?

# 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作爲列表返回。

這是我的問題,在此基礎上分析:

  1. 這是什麼功能next?它從來沒有定義也沒有提供,但怎麼沒有錯誤報告?
  2. 總結當get_in被函數調用(在本例中爲all)作爲關鍵字時,它是否正確地返回該函數的結果中的鍵的值(在本例中爲:age)?
  3. 如果我在2中的猜測是正確的,那麼當該函數的結果不是字典類型並且沒有鍵值對時會發生什麼?它會引起錯誤嗎?

回答

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將在上一步中匹配,遞歸將開始揭曉。

+0

謝謝。我不敢相信看到源代碼的想法不在我腦海。現在一切都說得通了。我認爲讓我感到沮喪的是,沒有明確提及在文檔中對'get_in'的遞歸調用。對於那些更熟悉FP的人來說,這很明顯,但是直到我看到源代碼之前,它並沒有清晰地呈現出來。 – Harfangk

+1

歡迎。 Elixir源代碼本身非常乾淨,在大多數情況下,它使得相對容易理解引擎蓋下發生了什麼。僅供參考:要直接從文檔訪問源代碼,可以簡單地按下相應功能描述右上角的''鏈接。 – mudasobwa

相關問題