Функция совпадения шаблонов с пустой картой
Я играю с совпадением с шаблоном, и я узнал, что не совсем легко сопоставить параметры сопоставления метода с пустой картой. Я думал, что это будет примерно так:
defmodule PatternMatch do
def modify(%{}) do
%{}
end
def modify(map) do
# expensive operation
%{ modified: "map" }
end
end
Но похоже, что первое предложение функции соответствует произвольным картам:
iex> PatternMatch.modify(%{a: "map"})
==> %{}
Есть ли другой способ проверить пустые карты?
Ответы
Ответ 1
Он работает таким образом по дизайну, но, по общему признанию, на первый взгляд может быть немного запутанным. Эта функция позволяет вам деструктурировать карты, используя сопоставление шаблонов, не указывая всех ключей. Например:
iex> %{b: value} = %{a: 1, b: 2, c: 3}
%{a: 1, b: 2, c: 3}
iex> value
2
Следовательно, %{}
будет соответствовать любой карте. Если вы хотите сопоставить пустую карту в функции, вы должны использовать предложение охраны:
defmodule PatternMatch do
def modify(map) when map == %{} do
%{}
end
def modify(map) do
# ...
end
end
Ответ 2
В дополнение к ответу @PatrickOscity (который я буду использовать для пустой карты) вы можете использовать map_size/1 охрану для сопоставления с картами с рядом клавиши:
defmodule PatternMatch do
def modify(map) when map_size(map) == 0 do
%{}
end
def modify(map) when map_size(map) == 1 do
#something else
end
def modify(map) do
# expensive operation
%{ modified: "map" }
end
end
Вот результат iex, используя Kernel.match?/2
, чтобы показать map_size/1
в действии:
iex(6)> Kernel.match?(map when map_size(map) == 1, %{})
false
iex(7)> Kernel.match?(map when map_size(map) == 1, %{foo: "bar"})
true