Elixir入门疑问:为何特定匿名列表拼接函数无法运行?
为什么你的Elixir匿名函数调用会报错?
嘿,这个问题核心在于Elixir匿名函数里的模式匹配规则,咱们来理清楚:
首先看你写的正确版本:
concat = fn(x,y) -> x ++ y end
这里的x和y是通用的变量绑定——不管你传什么可拼接的数据类型(列表、字符串甚至字符列表),Elixir都会把传入的参数绑定到这两个变量上,然后执行++操作,所以它能适配多种数据类型。
再看你出问题的函数:
list_concat = fn([:a,:b],[:c,:d]) -> [:a,:b,:c,:d] end
这里的参数可不是通用变量,而是固定的模式匹配规则!这个函数子句只认一种调用情况:第一个参数必须是精确的[:a,:b],第二个参数必须是精确的[:c,:d]。当你调用list_concat.([:true,:false],[:false,:true])时,传入的参数和这个固定模式完全不匹配,Elixir找不到能处理这个调用的函数子句,自然就抛出FunctionClauseError了。
修正方案
如果你想让这个函数能拼接任意两个列表,只需要把参数改成通用变量即可:
list_concat = fn(list1, list2) -> list1 ++ list2 end
这样不管你传原子列表、布尔值列表还是其他类型的列表,只要是符合++操作要求的列表,都能正常工作。
如果想进一步限制参数必须是列表(避免传入非列表导致++报错),可以加上守卫条件:
list_concat = fn(list1, list2) when is_list(list1) and is_list(list2) -> list1 ++ list2 end
这样如果传入非列表参数,会抛出更明确的守卫条件不满足的错误,方便调试。
内容的提问来源于stack exchange,提问作者bparikh
相关产品推荐
相关产品推荐

