Elixir 使用 行為 這種程式碼機制來提供通用介面,並讓每個實作該行為的模組能有各自的特定實作。其中一個常見例子就是 Access 行為。
Access 行為 提供一個通用介面,可從以鍵為基礎的資料結構中取出資料。Access 行為 已為 map 和關鍵字清單實作,但我們先來看看它在 map 上的用法,感受一下。Access 行為 規定:當你有一個 map 時,可以在後面加上 方括號,然後用鍵取出與該鍵相關的值。
# Suppose we have these two maps defined (note the difference in the key type)
my_map = %{key: "my value"}
your_map = %{"key" => "your value"}
# Obtain the value using the Access Behaviour
my_map[:key] == "my value"
your_map[:key] == nil
your_map["key"] == "your value"
如果資料結構中沒有這個鍵,就會回傳nil。這可能導致非預期的行為,因為它不會引發錯誤。請注意,nil本身也實作了 Access 行為,而且對任何鍵都會回傳nil。
你正與一個網站開發團隊合作,維護一支當地籃球隊的網站。這個團隊對 Elixir 比較不熟悉,因此希望有一個函式能從一連串巢狀的 map 中擷取資料,讓開發更快速。
實作extract_from_path/2函式,它接受兩個引數:
data:一個巢狀的 map 結構,裡面是這支籃球隊的資料。path:一個以句點分隔鍵的字串,用來取得最後一個鍵所對應的值。如果路徑中任何一個環節的值或鍵不存在,就應該回傳 nil。
data = %{
"team_mascot" => %{
"animal" => "bear",
"actor" => %{
"first_name" => "Noel"
}
}
}
BasketballWebsite.extract_from_path(data, "team_mascot.animal")
# => "bear"
BasketballWebsite.extract_from_path(data, "team_mascot.colors")
# => nil
實作這個函式時,請使用 Access Behaviour。
處理巢狀 map 資料結構時,請不要使用任何 Map 或 Kernel 模組函式。
審查你程式的同事告訴你,Kernel 模組裡有一個函式和你目前的實作非常相似。
請實作 get_in_path/2,改用這個 Kernel 模組函式。
它預期的引數和第 1 部分相同。
BasketballWebsite.get_in_path(data, "team_mascot.actor.first_name")
# => "Noel"