gpt4 book ai didi

pattern-matching - 如何在 Elixir 的功能头中对映射键进行模式匹配

转载 作者:行者123 更新时间:2023-12-03 20:29:45 24 4
gpt4 key购买 nike

我似乎找不到在函数头中对 map 键进行模式匹配的方法。有没有办法做到这一点?我想要做的是根据 map 中是否已经存在某个键来运行不同的代码(并且还想避免 if/else 等)

这就是我的代码的样子

def my_func(key, %{key => _} = map), do: ...

这给了我这个错误

** (CompileError) illegal use of variable key inside map key match, maps can only match on existing variable by using ^key



当然,我也尝试使用 ^
def my_func(key, %{^key => _} = map), do: ...

然后给出

** (CompileError) unbound variable ^key



我在 Windows 8.1 机器上使用 elixir 1.3.1/erlang 19.0 x64。
谢谢阅读!

最佳答案

您可以根据具体问题和您使用的 Elixir 版本尝试多种方法:

  • map 模式匹配
  • 检查给定 key 是否存在 (Elixir < 1.10)
  • 检查给定 key 是否存在 (Elixir >= 1.10)

  • map 模式匹配

    如果您可以使用所需的键进行模式匹配:
    defmodule Test do
    def my_func(%{"a" => value}), do: {:a, value}
    def my_func(%{"b" => value}), do: {:b, value}
    def my_func(_), do: :error
    end

    然后在IEx中:
    iex(1)> Test.my_func(%{"a" => 1})
    {:a, 1}
    iex(2)> Test.my_func(%{"b" => 2})
    {:b, 2}

    条款的顺序也很重要,例如如果您尝试匹配 %{"b" => 2}但是你有以下 map %{"a" => 1, "b" => 2} , 关键 "a"将首先匹配,因为 is 在第一个子句中:
    iex(3)> Test.my_func(%{"a" => 1, "b" => 2})
    {:a, 1}

    如果您想为每个可以匹配的键生成一些东西,我推荐一种不同的方法。例如,如果要将函数映射到这些键:
    defmodule Test0 do
    def my_op({"times_2", value}), do: {"times_2", value * 2}
    def my_op({"times_3", value}), do: {"times_3", value * 3}
    def my_op({key, value}), do: {key, value}

    def my_func(m) do
    Enum.map(m, &my_op/1) |> Enum.into(%{})
    end
    end

    所以你会得到以下信息:
    iex(1)> Test0.my_func(%{"times_2" => 2, "times_3" => 3, "whatever" => 42})
    %{"times_2" => 4, "times_3" => 9, "whatever" => 42}

    检查给定 key 是否存在(Elixir < 1.10)

    您不能将键与变量进行模式匹配。问题是编译器需要生成代码来搜索它还不知道的东西。当你进行模式匹配时,你通常会给编译器一些关于它将接收什么的提示。对于 map 中的键,提示是键本身。在这种情况下,即使指出第一个参数应该是要查找的关键,对于编译器来说也是不够的。所以你的方法应该是使用 if 语句:
    defmodule Test1 do
    def my_func(k, m) do
    if Map.has_key?(k, m) do
    ... do something when key is found ...
    else
    ... do something when key is not found ...
    end
    end
    end

    检查给定 key 是否存在(Elixir >= 1.10)

    Elixir 1.10 增加了保护 is_map_key/2终于可以用来解决这个问题了!
    defmodule Test2 do
    def my_func(key, map) when is_map_key(map, key) do
    ... key is found ...
    end

    def my_func(_, _) do
    ... key is not found ...
    end
    end

    这肯定会解决编译问题:)

    我希望这回答了你的问题。

    关于pattern-matching - 如何在 Elixir 的功能头中对映射键进行模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38221126/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com