正则表达式和地图参数匹配
Regex and Map argument matching
在编写函数时,我正在使用参数匹配,如下所示:
def process_thing( %{} = thing )
我希望 thing
是一个 Map,并且是可枚举的。不幸的是,这个参数列表也匹配指定为 ~r/regex/
的正则表达式,并且正则表达式(尽管它 returns 对于 is_map(~r/thing/)
为真)不是可枚举的。
我如何设计这个函数定义,以便只有映射——或者理想情况下,可枚举的东西——被分派到这个函数?
无法匹配 Enumerable
。如果您只接受地图,那么您可以使用 is_map/1
内置函数:
def process_thing(thing) when is_map(thing) do
...
end
另一种方法是检查您期望和支持的所有数据类型:
def process_thing(thing) when is_map(thing) or is_list(thing), do: ...
def process_thing(%MapSet{}), do: ...
...
如果你需要支持 all 可枚举(也许提供更多关于你的用例的信息会更容易给出好的建议),你总是可以使用 Protocol.assert_impl!/2
:
def process_thing(thing) when is_map(thing) or is_list(thing), do: ...
def process_thing(%{__struct__: struct}) do
assert_impl!(Enumerable, struct)
end
并处理Protocol.assert_impl!/2
可能出现的故障。我不确定这个实现是否是防弹的,而且可能有更简洁的方法来实现它。 :)
还有一件事:如果你想在地图上匹配而不是在结构上匹配(比如Regex
),解决它的一种方法是首先匹配你不要的东西t 想要匹配,这样你就可以将它们移开(并根据需要处理它们):
def process_thing(%{__struct__: _}), do: # bad things here, we don't like structs
def process_thing(%{} = thing), do: # hey, that's a map now!
在编写函数时,我正在使用参数匹配,如下所示:
def process_thing( %{} = thing )
我希望 thing
是一个 Map,并且是可枚举的。不幸的是,这个参数列表也匹配指定为 ~r/regex/
的正则表达式,并且正则表达式(尽管它 returns 对于 is_map(~r/thing/)
为真)不是可枚举的。
我如何设计这个函数定义,以便只有映射——或者理想情况下,可枚举的东西——被分派到这个函数?
无法匹配 Enumerable
。如果您只接受地图,那么您可以使用 is_map/1
内置函数:
def process_thing(thing) when is_map(thing) do
...
end
另一种方法是检查您期望和支持的所有数据类型:
def process_thing(thing) when is_map(thing) or is_list(thing), do: ...
def process_thing(%MapSet{}), do: ...
...
如果你需要支持 all 可枚举(也许提供更多关于你的用例的信息会更容易给出好的建议),你总是可以使用 Protocol.assert_impl!/2
:
def process_thing(thing) when is_map(thing) or is_list(thing), do: ...
def process_thing(%{__struct__: struct}) do
assert_impl!(Enumerable, struct)
end
并处理Protocol.assert_impl!/2
可能出现的故障。我不确定这个实现是否是防弹的,而且可能有更简洁的方法来实现它。 :)
还有一件事:如果你想在地图上匹配而不是在结构上匹配(比如Regex
),解决它的一种方法是首先匹配你不要的东西t 想要匹配,这样你就可以将它们移开(并根据需要处理它们):
def process_thing(%{__struct__: _}), do: # bad things here, we don't like structs
def process_thing(%{} = thing), do: # hey, that's a map now!