【问题标题】:IF statement between ints and atoms整数和原子之间的 IF 语句
【发布时间】:2021-12-29 20:41:02
【问题描述】:

我已经在这段代码中搞砸了几个小时,但我仍然不知道我做错了什么我有其他功能,这是我唯一遇到问题的功能。

-module(if_statements).

-export([weather/1]).

weather(TEMP) ->

if 

    TEMP <= 0 ->

        io:fwrite("freezing\\n");

    0 < TEMP <= 10 ->

        io:fwrite("cold\\n");

    10 < TEMP <= 20 ->

        io:fwrite("normal\\n");

    20 < TEMP <= 30 -> 

        io:fwrite("hot\\n");

    30 < TEMP <= 40 -> 

        io:fwrite("heated\\n");

    40 < TEMP ->

        io:fwrite("hirviendo\\n").

    true -> 

        io:fwrite("unknown")

end.

壳牌: shell 也不是很有帮助

if_statements.erl:6:8: syntax error before: '<='

% 6| TEMP <= 0 ->

% | ^



if_statements.erl:18:8: syntax error before: '->'

% 18| true ->

% | ^



if_statements.erl:2:2: function clima/1 undefined

% 2| -export([weather/1]).

% |

【问题讨论】:

  • 1.在 erlang 中,“小于或等于”拼写为 =&lt;。符号&lt;= 用于其他称为二进制理解 的东西。 2.在erlang中,你用句点终止一个表达式,但你的if表达式中间有一个句点。在 erlang 中,您不能只在有效表达式的末尾添加代码——标点符号必然需要更改。
  • 我认为我从未见过使用if 语句的erlang 生产代码。首选/最佳实践方法是通过模式匹配和函数头。下面有一些答案展示了使用模式匹配的良好解决方案。

标签: erlang


【解决方案1】:

@alias 答案是正确的,尽管我很确定最终的true 子句永远不会匹配,因为无论TEMP 的值如何,它总是属于前面的子句之一。 OTOH,您可能需要考虑 avoiding if statements altogether 并仅使用带保护的多子句函数……

weather(TEMP) when            TEMP =< 0  -> io:fwrite("freezing\n");
weather(TEMP) when  0 < TEMP, TEMP =< 10 -> io:fwrite("cold\n");
weather(TEMP) when 10 < TEMP, TEMP =< 20 -> io:fwrite("normal\n");
weather(TEMP) when 20 < TEMP, TEMP =< 30 -> io:fwrite("hot\n");
weather(TEMP) when 30 < TEMP, TEMP =< 40 -> io:fwrite("heated\n");
weather(TEMP) when 40 < TEMP             -> io:fwrite("boiling ;)\n");
weather(TEMP) -> io:format("unknown temperature: ~p", [TEMP]).

【讨论】:

    【解决方案2】:

    你的语法有点不对劲。请尝试以下操作:

    -module(if_statements).
    -export([weather/1]).
    
    weather(TEMP) ->
      if
          TEMP =< 0            -> io:fwrite("freezing\n");
          0 < TEMP, TEMP =< 10 -> io:fwrite("cold\n");
         10 < TEMP, TEMP =< 20 -> io:fwrite("normal\n");
         20 < TEMP, TEMP =< 30 -> io:fwrite("hot\n");
         30 < TEMP, TEMP =< 40 -> io:fwrite("heated\n");
         40 < TEMP             -> io:fwrite("hirviendo\n");
         true                  -> io:fwrite("unknown")
    end.
    

    【讨论】:

      【解决方案3】:

      函数子句(或 if 条件)可以简单地如下所示:

      weather2(TEMP) when TEMP =< 0  -> "freezing";
      weather2(TEMP) when TEMP =< 10 -> "cold";
      weather2(TEMP) when TEMP =< 20 -> "normal";
      weather2(TEMP) when TEMP =< 30 -> "hot";
      weather2(TEMP) when TEMP =< 40 -> "heated";
      weather2(_) -> "unknown".  %% this clause only matches if TEMP is greater than 40
      
      test() ->
          print_weather(-10),
          print_weather(7),
          print_weather(20),
          print_weather(21),
          print_weather(35),
          print_weather(45),
          test_finished.
      
      
      print_weather(TEMP) ->
          io:format("~3w => ~s~n", [TEMP, weather2(TEMP)] ).
      

      与 if 表达式类似,erlang 检查第一个函数子句,如果匹配,则执行该函数子句,之后不再检查后续函数子句。如果子句不匹配,则检查下一个函数子句,等等。

      输出:

      ~/erlang_programs$ erl
      Erlang/OTP 24 [erts-12.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]
      Eshell V12.0.2  (abort with ^G)
      
      1> c(a).
      a.erl:2:2: Warning: export_all flag enabled - all functions will be exported
      %    2| -compile(export_all).
      %     |  ^
      
      {ok,a}
      
      2> a:test().
      -10 => freezing
        7 => cold
       20 => normal
       21 => hot
       35 => heated
       45 => unknown
      test_finished
      
      3> 
      

      另外,在 erlang 中非常不同(虽然这里不相关)是函数子句的参数可以是常量:

      f1(X, 10) -> ... ;  %integer
      f1(X, a)  -> ....;  %atom
      f1(X, "hello") -> ...; %string (which is a shortcut for creating a list)
      f1(3, [Name, Age, Phone]) -> something.
      

      在大多数语言中,函数定义中的所有参数都必须是变量。

      在erlang中,函数子句匹配是一种非常强大的方法来剖析参数以及控制执行流程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-14
        • 1970-01-01
        • 2016-05-07
        • 2013-01-16
        • 2012-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多