Почему в Elixir Kernel.put_in/3 определен в модуле ядра, а не в модуле карты?

#elixir

#elixir

Вопрос:

При обновлении значения во вложенной карте в Elixir мы можем использовать Kernel.put_in/3

 map = %{hi: "what's", up: %{my: "boii"}}
%{hi: "what's", up: %{my: "boii"}}

Kernel.put_in(map, [:up, :my], "dawg") 
%{hi: "what's", up: %{my: "dawg"}}
  

Почему эта функция не определена наряду Map.put/3 с учетом того, что их входные данные и результаты очень похожи?

Ответ №1:

Функция Kernel.put_in работает в любой структуре, которая обладает поведением доступа, согласно ее документации:

 @spec put_in(Access.t(), nonempty_list(term), term) :: Access.t()
def put_in(data, [_ | _] = keys, value) do
  elem(get_and_update_in(data, keys, fn _ -> {nil, value} end), 1)
end
  

Поведение доступа поддерживается как картами, так и списками ключевых слов, поэтому put_in не является эксклюзивным для карт, поэтому находится в модуле ядра.

Пример использования в списках ключевых слов:

 iex(1)> Kernel.put_in([foo: 3], [:foo], 4)
[foo: 4]
iex(2)> Kernel.put_in([foo: [bar: 3]], [:foo, :bar], 4)
[foo: [bar: 4]]