【问题标题】:Head Mismatch in simple argument pattern matching简单参数模式匹配中的头部不匹配
【发布时间】:2015-03-16 14:36:31
【问题描述】:

我有这个代码:

-module(info).
-export([map_functions/0]).
-author("me").



map_functions() ->
    {Mod,_} = code:all_loaded(),
    map_functions(Mod,#{});
map_functions([H|Tail],A) ->
    B = H:mod_info(exports),
    map_functions(Tail,A#{H => B});
map_functions([],A) -> A.

但是,每当我编译它时,我都会在第 10 行得到一个头部不匹配,这是

map_funtions([H|Tail],A) ->

我确定这是一个非常基本的错误,但我无法理解为什么它不运行。这是一个正确的模式匹配语法[H|Tail],三个同名但不同arities的函数用逗号分隔。

【问题讨论】:

标签: erlang pattern-matching head mismatch


【解决方案1】:

同名但元数不同的函数不同,用点分隔。

code:all_loaded 返回一个列表,所以应该写第一个函数:

map_functions() ->
    Mods = code:all_loaded(),
    map_functions(Mods, #{}).

生成的 Mods 列表是 {ModName,BeamLocation} 形式的元组列表,因此应编写第二个函数:

map_functions([], A)       -> A;
map_functions([{ModName,_}|Tail], A) ->
    B = ModName:module_info(exports),
    map_functions(Tail, A#{ModName => B}).

请注意,您应该深入研究 erlang 库并尝试使用更惯用的代码形式,整个函数,使用列表理解,可以编写:

map_functions() ->
     maps:from_list([{X,X:module_info(exports)} || {X,_} <- code:all_loaded()]).

【讨论】:

    【解决方案2】:

    你的函数定义应该是

    map_functions() ->
        {Mod,_} = code:all_loaded(),
        map_functions(Mod, #{}).
    
    map_functions([], A)       -> A;
    map_functions([H|Tail], A) ->
        B = H:mod_info(exports),
        map_functions(Tail, A#{H => B}).
    

    名称map_functions 相同,但数量不同。在 Erlang 世界中,这意味着这是两个完全不同的函数:map_functions/0map_functions/2

    另外,请注意,我在map_functions/2 中将“基本情况”放在首位(并使第一个子句的返回值突出——将其分成两行更为常见,但无论如何)。这是出于三个原因:清晰,养成先写基本情况的习惯(这样你就不会不小心写出无限循环),而且经常有必要这样做,这样你就不会意外地掩盖你的基本情况匹配更高优先级子句中的每个参数。

    关于这个主题的一些扩展讨论在这里(针对 Elixir 和 Erlang):Specify arity using only or except when importing function on Elixir

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多