给定一个MapSet,如何使用模式匹配检测它是否为空?
# What goes in the question marks?
def my_func(????), do: IO.puts("This mapset is empty")
def my_func(%MapSet{}), do: IO.puts("This mapset is not empty")
my_func(MapSet.new())
如果这是一个列表,我会在([])
上匹配它,但这对MapSets不起作用(因为类型不同)
以下是我尝试过的其他一些事情,但未成功。
def myfunc([]), do: IO.puts("This only works for lists")
# This is a syntax error
# def myfunc(MapSize.new())
def myfunc(%MapSet{}), do: IO.puts("This matches every mapset")
def myfunc(a) when map_size(a), do: IO.puts("the map size is always 3")
答案 0 :(得分:5)
MapSet将其条目存储在名为map
的字段中。我不能100%确定这是实施细节还是保证保持不变,但现在您可以使用map
检查map_size/1
字段是否为空:
defmodule A do
def empty?(%MapSet{map: map}) when map_size(map) == 0, do: true
def empty?(%MapSet{}), do: false
end
IO.inspect A.empty?(MapSet.new)
IO.inspect A.empty?(MapSet.new([1, 2]))
输出:
true
false
答案 1 :(得分:3)
您也可以考虑the solution I provided for matching against an empty map如下:
defmodule A do
def empty?(some_map_set = %MapSet{}) do
an_empty_map_set = MapSet.new
some_map_set
|> case do
^an_empty_map_set ->true # Application of pin operator
_ -> false
end
end
end
您可以按如下方式进行测试:
A.empty?(MapSet.new)
和
A.empty?(MapSet.new([1]))
在该链接中,您可以看到可以相应利用的其他解决方案。 一个已经由@dogbert提供。 另一种解决方案可以如下工作:
defmodule A do
@empty MapSet.new
def empty?(some_map_set) when some_map_set == @empty, do: true
def empty?(%MapSet{}), do: false
end
答案 2 :(得分:3)
实现目标有一种愚蠢但仍然合法的方式:
defmodule MapSetTest do
def my_func(map_set, empty_map_set \\ MapSet.new)
def my_func(empty_map_set, empty_map_set),
do: IO.puts("This mapset is empty")
def my_func(%MapSet{}, _),
do: IO.puts("This mapset is not empty")
end
MapSetTest.my_func(MapSet.new) #⇒ This mapset is empty
MapSetTest.my_func(MapSet.new([])) #⇒ This mapset is empty
MapSetTest.my_func(MapSet.new([1])) #⇒ This mapset is not empty
这里的诀窍是,虽然我们不能直接在匹配中调用MapSet.new
,但我们可以将其值指定为隐藏的第二个参数的默认值。