Erlang-其他条件

时间:2018-07-20 01:36:47

标签: if-statement erlang

尝试计算分数并将其保持在0.2到1.5之间。 下面的代码可以工作吗?我不希望它返回,但请继续。

     ok = if
       Score > 1.5 ->
         Score = 1.5;
       true ->
         ok
     end,
      ok =   if
             Score < 0.2 ->
                 Score = 0.2;
             true ->
                 ok
         end,
    put(score, Score),

2 个答案:

答案 0 :(得分:9)

  

下面的代码可以工作吗?

不。在erlang中,您只能分配一次变量。那是您应该学的第一件事。在此语句中:

 if
       Score > 1.5 -> ...

已经为变量Score分配了一个值,您正在将其与小数点1.5进行比较。假设Score的值为2.0,那么特定if子句的主体将执行:

 Score = 1.5;

那等于写:

 2.0 = 1.5;

这将导致模式匹配错误:

  
      
  • 异常错误:右侧值1.5不匹配。
  •   

在erlang中,一旦给变量赋值,此后对该变量的任何后续赋值将被视为模式匹配,即等号右侧的值将与左侧的值进行模式匹配等号。


在erlang中,通常使用多个函数子句来模式匹配不同的值:

-module(my).
-compile(export_all).

compute(Score) when Score > 1.5 ->
    1.5;
compute(Score) when Score < 0.2 ->
    0.2;
compute(Score) ->
    Score.

在外壳中:

1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}

2> Score1 = my:compute(1.6).
1.5

3> Score2 = my:compute(1.5).
1.5

4> Score3 = my:compute(1.2).
1.2

5> Score4 = my:compute(0.1).
0.2

6> Score5 = my:compute(0.2). 
0.2

然后您可以在同一模块中定义另一个函数,如下所示:

do_stuff(Score) ->
    NewScore = compute(Score),
    %Do something with NewScore here...

如果您要使用if语句,我会这样做:

-module(my).
-compile(export_all).

do_stuff(Score) ->
    NewScore = if 
                   Score > 1.5   -> 1.5;
                   Score < 0.2   -> 0.2;
                   true          -> Score
               end,
    %Do something with NewScore here, for instance:
    io:format("~w~n", [NewScore]).

为了使您的函数不超过5-6行,这将有助于将该if语句移至另一个函数。

答案 1 :(得分:4)

另一种方法是使用erlang:min/2erlang:max/2来保持范围:

-module(my).
-compile(export_all).

do_stuff(Score) ->
    max(min(Score, 1.5), 0.2).

如果Score大于1.5,则min/2将返回1.5,否则返回Score。然后,如果该结果小于0.2,则max/2将返回0.2,否则返回min/2的结果。这是我们的测试功能:

test_do_stuff() ->
    ScoresAndResults = [{0, 0.2},
                        {1.5, 1.5},
                        {0.2, 0.2},
                        {1.4999999, 1.4999999},
                        {1.5000001, 1.5},
                        {42, 1.5},
                        {0.19999999, 0.2},
                        {0.2000000000001, 0.2000000000001},
                        {1.2, 1.2},
                        {1, 1},
                        {-1, 0.2}],
    {Scores, Results} = lists:unzip(ScoresAndResults),
    Results = [do_stuff(Score) || Score <- Scores].

运行它会产生预期的结果:

1> my:test_do_stuff().
[0.2,1.5,0.2,1.4999999,1.5,1.5,0.2,0.2000000000001,1.2,1,0.2]