如何匹配函数头中不存在的映射键

How to match on non-existing key of map in function head

我有一个函数维护一些值作为其递归的状态,为了灵活处理其参数的顺序,我使用 Map 来存储状态并在调用之间传递它.

我的基本情况是函数在没有 socket 的情况下被调用,因此应该存在只完成该设置的情况。但是,我找不到匹配 Map.

的不存在的键的方法

尝试:

def measure(args = %{socket: nil}) ...

def measure(args = %{socket: socket}) when not is_port(socket) ...

但是,这些模式仅在 存在 socketnil/不是端口时才匹配。

有没有办法指定与不存在的键匹配的模式?还是我必须创建另一个 entry 函数来为我的地图提供默认值?

您需要一个匹配任何值的子句并在之后添加另一个子句:

def measure(args = %{socket: socket}) do
  handle_socket(socket, args)
end

def measure(args) do
  handle_without_socket(args)
end

一般来说,使用地图的首选方式是通过严格的语法。您只需匹配 :socket 或调用 args.socket,如果套接字不可用作键,它将失败。

如果您要传递可选数据,也许您想使用关键字列表而不是地图。

Elixir 版本 1.10.0 引入了一个名为 is_map_key (https://hexdocs.pm/elixir/Kernel.html#is_map_key/2)

的新守卫

您现在可以处理映射中不存在的键,例如:

def measure(args) when not is_map_key(args, :socket) do
  handle_without_socket(args)
end

def measure(args = %{socket: socket}) do
  handle_socket(socket, args)
end