Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pattern matching 针对空映射的模式匹配函数_Pattern Matching_Elixir - Fatal编程技术网

Pattern matching 针对空映射的模式匹配函数

Pattern matching 针对空映射的模式匹配函数,pattern-matching,elixir,Pattern Matching,Elixir,我在玩弄模式匹配,我发现,根据空映射模式匹配方法的参数并不容易。我以为会是这样的: defmodule PatternMatch do def modify(%{}) do %{} end def modify(map) do # expensive operation %{ modified: "map" } end end 但第一个function子句似乎匹配任意映射: iex> PatternMatch.modify(%{a: "map"}

我在玩弄模式匹配,我发现,根据空映射模式匹配方法的参数并不容易。我以为会是这样的:

defmodule PatternMatch do
  def modify(%{}) do
    %{}
  end

  def modify(map) do
    # expensive operation
    %{ modified: "map" }
  end
end
但第一个function子句似乎匹配任意映射:

iex> PatternMatch.modify(%{a: "map"})
==> %{}

有没有其他方法可以检查空地图?

这种方法是设计出来的,但必须承认,乍一看可能有点混乱。此功能允许您使用模式匹配来分解贴图,而无需指定所有关键点。例如:

iex> %{b: value} = %{a: 1, b: 2, c: 3}
%{a: 1, b: 2, c: 3}

iex> value
2
因此,
%{}
将匹配任何映射。如果要匹配函数中的空映射,必须使用guard子句:

defmodule PatternMatch do
  def modify(map) when map == %{} do
    %{}
  end

  def modify(map) do
    # ...
  end
end

除了@PatrickOscity的答案(我会将其用于空地图)之外,您还可以使用一个守卫来匹配具有多个键的地图:

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使用
内核.match?/2
的输出,以显示
映射大小/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

除了迄今为止提供的所有酷答案之外,你也可以考虑使用看起来像帽子或上箭头点的东西。您可以使用它作为变量的前缀,以确保模式与其值匹配,如相关文档中所述:

当您要与图形匹配时,请使用pin运算符^ 现有变量的值,而不是重新绑定变量

以下是一个例子:

defmodule A do
  def determine_map_volume(some_map) do
    an_empty_map = %{}

    some_map
    |> case do
    ^an_empty_map -> :empty  # Application of pin operator
    _ -> :not_empty
    end
  end
end
您可以通过以下方式验证:

A.determine_map_volume(%{})
:empty
A.determine_map_volume(%{a: 1})
:not_empty

您打算使用哪种方法取决于您个人/组织对代码可读性的偏好。

Nice addition。小更正:我认为它应该是
当地图大小(map).
而不是
当地图大小…
很好的发现!谢谢。功能条款的顺序也会影响到这个问题吗?我的意思是一个空映射是否总是匹配的,因此需要成为最后一个函数子句?我在
%{}
上进行了模式匹配,以告诉我的代码,在数据库中存储空映射时没有必要这样做。。。这就是所谓的bug。我很惊讶,因为我忘了我以前在书中读过的东西。这意味着10天内数据库中没有数据。幸运的是,这是一个开发设置