Elixir語言中 Kernel.get_and_update_in
相關用法介紹如下。
用法一
get_and_update_in(path, fun)
(宏)
通過給定的 path
獲取值並更新嵌套數據結構。
這類似於
,除了路徑是通過宏提取而不是傳遞列表。例如:get_and_update_in/3
get_and_update_in(opts[:foo][:bar], &{&1, &1 + 1})
相當於:
get_and_update_in(opts, [:foo, :bar], &{&1, &1 + 1})
這也適用於嵌套結構和 struct.path.to.value
指定路徑的方式:
get_and_update_in(struct.foo.bar, &{&1, &1 + 1})
請注意,為了使此宏工作,完整路徑必須始終對此宏可見。請參閱下麵的"Paths" 部分。
例子
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}}
iex> get_and_update_in(users["john"].age, &{&1, &1 + 1})
{27, %{"john" => %{age: 28}, "meg" => %{age: 23}}}
路徑
路徑可以以變量、本地或遠程調用開始,並且必須後跟一個或多個:
-
foo[bar]
- 訪問foo
中的 keybar
;如果foo
為 nil,則返回nil
-
foo.bar
- 訪問映射/結構字段;如果該字段不存在,則會引發錯誤
以下是一些有效路徑:
users["john"][:age]
users["john"].age
User.all()["john"].age
all_users()["john"].age
以下是一些無效的:
# Does a remote call after the initial value
users["john"].do_something(arg1, arg2)
# Does not access any key or field
users
用法二
get_and_update_in(data, keys, fun)
@spec get_and_update_in(
structure,
keys,
(term() | nil -> {current_value, new_value} | :pop)
) :: {current_value, new_structure :: structure}
when structure: Access.t(),
keys: [any(), ...],
current_value: Access.value(),
new_value: Access.value()
獲取一個值並更新一個嵌套結構。
data
是一個嵌套結構(即實現
行為的映射、關鍵字列表或結構)。Access
fun
參數接收 key
的值(或 nil
,如果 key
不存在)並且必須返回以下值之一:
-
一個二元素元組
{current_value, new_value}
。在這種情況下,current_value
是檢索到的值,可以在返回之前對其進行操作。new_value
是要存儲在key
下的新值。 -
:pop
,這意味著key
下的當前值應從結構中刪除並返回。
此函數使用
模塊根據給定的 Access
keys
遍曆結構,除非 key
是一個函數,這將在後麵的部分中詳細介紹。
例子
當需要檢索當前值(或根據當前值計算的值)並同時更新它時,此函數很有用。例如,它可以用於讀取用戶的當前年齡,同時將其增加一倍:
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}}
iex> get_and_update_in(users, ["john", :age], &{&1, &1 + 1})
{27, %{"john" => %{age: 28}, "meg" => %{age: 23}}}
請注意,賦予匿名函數的當前值可能是 nil
。如果任何中間值為零,它將引發:
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}}
iex> get_and_update_in(users, ["jane", :age], &{&1, &1 + 1})
** (ArgumentError) could not put/update key :age on a nil value
作為鍵的函數
如果鍵是一個函數,該函數將被調用並傳遞三個參數:
- 操作(
:get_and_update
) - 要訪問的數據
- 接下來要調用的函數
這意味著可以擴展
以提供自定義查找。缺點是函數不能作為鍵存儲在訪問的數據結構中。get_and_update_in/3
當其中一個鍵是函數時,調用該函數。在下麵的示例中,我們使用一個函數來獲取和遞增列表中的所有年齡:
iex> users = [%{name: "john", age: 27}, %{name: "meg", age: 23}]
iex> all = fn :get_and_update, data, next ->
...> data |> Enum.map(next) |> Enum.unzip()
...> end
iex> get_and_update_in(users, [all, :age], &{&1, &1 + 1})
{[27, 23], [%{name: "john", age: 28}, %{name: "meg", age: 24}]}
如果調用函數之前的前一個值是 nil
,則函數 will
接收 nil
作為值並且必須相應地處理它(無論是失敗還是提供合理的默認值)。
模塊附帶許多便利訪問器函數,例如上麵定義的Access
all
匿名函數。請參閱
、 Access.all/0
和其他示例。Access.key/2
相關用法
- Elixir Kernel.get_in用法及代碼示例
- Elixir Kernel.SpecialForms.case用法及代碼示例
- Elixir Kernel.round用法及代碼示例
- Elixir Kernel.left / right用法及代碼示例
- Elixir Kernel.put_in用法及代碼示例
- Elixir Kernel.tl用法及代碼示例
- Elixir Kernel.left - right用法及代碼示例
- Elixir Kernel.tuple_size用法及代碼示例
- Elixir Kernel.defexception用法及代碼示例
- Elixir Kernel.to_charlist用法及代碼示例
- Elixir Kernel.base ** exponent用法及代碼示例
- Elixir Kernel.left !== right用法及代碼示例
- Elixir Kernel.if用法及代碼示例
- Elixir Kernel.spawn_monitor用法及代碼示例
- Elixir Kernel.to_string用法及代碼示例
- Elixir Kernel.length用法及代碼示例
- Elixir Kernel.first..last用法及代碼示例
- Elixir Kernel.SpecialForms.%{}用法及代碼示例
- Elixir Kernel.SpecialForms.for用法及代碼示例
- Elixir Kernel.then用法及代碼示例
- Elixir Kernel.spawn用法及代碼示例
- Elixir Kernel.defmodule用法及代碼示例
- Elixir Kernel.SpecialForms.quote用法及代碼示例
- Elixir Kernel.left > right用法及代碼示例
- Elixir Kernel.binding用法及代碼示例
注:本文由純淨天空篩選整理自elixir-lang.org大神的英文原創作品 Kernel.get_and_update_in(path, fun)。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。