【问题标题】:Syntax error in a guard causing undefined function守卫中的语法错误导致未定义的函数
【发布时间】:2020-05-02 21:02:54
【问题描述】:

我不知道是什么问题, 这是代码-

solve_bdd(BddTree, ListVars) ->
  findRes(BddTree, maps:from_list(ListVars++[{one, 1}, {zero, 0}])).
findRes(BddTree, Map) when is_record(BddTree, node)-> Val = maps:get(getName(BddTree)), Name = getName(BddTree),
  if Name=='one' or Name=='zero' -> maps:get(getName(BddTree));
     (Val==1 or Val=='true') -> findRes(getRight(BddTree), Map);
     (Val==0 or Val=='false') -> findRes(getLeft(BddTree), Map);
     true -> error
  end;
findRes(_, _) -> error.

还有shell错误-

exf.erl:183: syntax error before: '=='
exf.erl:180: function findRes/2 undefined
exf.erl:21: Warning: function getRight/1 is unused
exf.erl:22: Warning: function getLeft/1 is unused
error

【问题讨论】:

    标签: erlang undefined guard


    【解决方案1】:

    当有多个条件时,应将or运算符的操作数放在括号中:

    1> false or false.
    false
    
    2> false == true or false == true.
    * 1: syntax error before: '=='
    
    2> (false == true) or (false == true).
    false
    

    还有你使用的maps:get/1(模块get中的函数maps接受1个参数):

    maps:get( getName(BddTree) )
    

    不存在!但是您可以使用maps:get/2maps:get/3

    大多数时候您可以使用case 表达式而不是if 表达式。
    此外,有时最好使用orlese 运算符而不是or
    最好什么都不处理!您可以使用其中一种并删除不必要的检查,而不是同时处理 01 以及布尔类型。
    按照 Erlang 的约定,最好在 Snake_case 中编写函数和记录名称。

    顺便说一句,您的 findRes/2 函数将类似于:

    %%% I don't know what work you expect from this function so if it's not working
    %%% just like your own, try to fix it!  
    
    % findRes -> find_res
    find_res(BddTree, Map) when is_record(BddTree, node) ->
      % Sounds like BddTree is a record. If by `get_name/1` you just want to
      % access one of it's elements, you can simply write BddTree#node.<ELEMENT_NAME>
      % getName -> get_name
      case get_name(BddTree) of
        % you don't have to use ' character for atoms:
        Name when Name == one orelse Name == zero ->
          % I thinkd you've missed `Map`:
          maps:get(get_name(BddTree), Map);
        _ -> 
          % I do not use 0 and 1 and just use boolean type:
          find_res(
            % I thinkd you've missed `Map`:
            case maps:get(get_name(BddTree), Map) of
              Val when Val -> % when Val == true
                % getRight -> get_right
                get_right(BddTree);
              _ -> % Assume false
                get_left(BddTree)
            end,
            Map
          )
      end;
    
    find_res(_, _) -> error.
    

    让我们看看上面没有 cmets 的代码:

    find_res(BddTree, Map) when is_record(BddTree, node) ->
      case get_name(BddTree) of
        Name when Name == one orelse Name == zero ->
          maps:get(get_name(BddTree), Map);
        _ -> 
          find_res(
            case maps:get(get_name(BddTree), Map) of
              Val when Val -> % when Val == true
                get_right(BddTree);
              _ ->
                get_left(BddTree)
            end,
            Map
          )
      end;
    find_res(_, _) -> error.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多