Elixir 如何检查映射是否也是结构?
在Elixir中,我可以通过调用有意义的函数来检查变量是Elixir 如何检查映射是否也是结构?,elixir,Elixir,在Elixir中,我可以通过调用有意义的函数来检查变量是map还是struct,因为我想区分两者。我知道我可以在一个结构上调用\uuuuuuuuuuuuuuuuuuuuuu来获取它的模块名,但在普通映射上调用它会抛出: **(KeyError)键:%{ 所以我的问题是,如何检查变量是映射还是结构? 示例用例: #我希望在模块中以不同的方式处理结构和映射输入 定义模块的不同内容 def do_something(arg)何时是_map(arg)do #用地图做点什么 结束 def do_som
map
还是struct
,因为我想区分两者。我知道我可以在一个结构上调用\uuuuuuuuuuuuuuuuuuuuuu
来获取它的模块名,但在普通映射上调用它会抛出:
**(KeyError)键:%{
所以我的问题是,如何检查变量是映射还是结构?
示例用例:
#我希望在模块中以不同的方式处理结构和映射输入
定义模块的不同内容
def do_something(arg)何时是_map(arg)do
#用地图做点什么
结束
def do_something(arg)何时是结构(arg)do
#但处理结构的方式不同
#问题是,`is_struct`不存在
结束
结束
您可以使用map.keys/1
轻松检查当前地图的键
对于map和structis_map/1
将返回true,但在您的示例中:
Map.keys(%{}) will return []
及
将返回密钥集合,例如[:\uuuuu struct\uuuuu,:name,:age]
因此,您可以简单地使用:
:__struct__ in Map.keys(struct).
如果您想让此为结构,请将其设置为宏。通常要检查映射是否为结构:
Map.has_key?(struct, :__struct__)
对于不同的方法声明(第二个是更通用的方法):
对于带有保护的Map和Struct,不能有单独的函数头,但可以通过模式匹配来实现
defmodule Guard do
def foo(%{:__struct__ => x }) do
Struct
end
def foo(x) when is_map x do
Map
end
end
可以像下面这样在struct和map之间进行模式匹配
defmodule DifferentThings do
def do_something(arg = %_x{}) do
IO.puts "This is a struct"
end
def do_something(arg = %{}) do
IO.puts "This is a map"
end
end
检查术语是否为地图的最简单方法是使用:
Map.has_键?(Map,:_结构)
它在保护中不起作用,因此我们以前不得不求助于模式匹配function子句中的:\uuuuu struct\uuuu
键:
def some_fun(%\uuuuu struct\uuuu:\u module}),do:。。。
但这件衣服看起来很脏
警卫:是结构/1
从Erlang/OTP 21开始,我们引入了两个新的防护装置,可用于定义我们自己的防护装置:
defguard在is_map(term)和:erlang.is_map_键(:_struct_,term)时为_struct(term)
当defguard是_struct(term)时,它是_struct(term,module)并且:erlang.map_get(:uuuu struct_u,term)==module
现在,您可以将其用作功能保护:
def do_some(account)结构(account,User)什么时候做
#使用%User{}结构执行某些操作
结束
什么时候做什么
#用随机结构做一些事情
结束
什么时候做什么
#用地图做点什么
结束
注意:这些将很快添加到Elixir标准库中。按照本文中的讨论进行操作。如前所述,介绍了防护装置。因此,您的原始代码将正常工作。这太完美了!谢谢大家!<代码>地图。有_键?(struct,:_struct_uu)
@OleksandrAvoyants-那好多了。请将其作为答案发布。如果您需要模式匹配,可以使用%{{code>arg=%{x}
非常喜欢arg=%{code>,但您也可以使用arg=%{}
。
defmodule Guard do
def foo(%{:__struct__ => x }) do
Struct
end
def foo(x) when is_map x do
Map
end
end
defmodule DifferentThings do
def do_something(arg = %_x{}) do
IO.puts "This is a struct"
end
def do_something(arg = %{}) do
IO.puts "This is a map"
end
end