Erlang 二郎初学者:找到周界?

Erlang 二郎初学者:找到周界?,erlang,Erlang,我正在学习Erlang,并试图解决上面提到的问题 所以,我的解决方案是 -module(mathStuff). -export([perimeter/1]). perimeter(Form) -> case element(1, Form) of square -> io:format("perimeter for square is ~p~n", [4*element(2, Form)]);

我正在学习Erlang,并试图解决上面提到的问题

所以,我的解决方案是

-module(mathStuff).
-export([perimeter/1]).

perimeter(Form) ->
        case element(1, Form) of
                square          -> io:format("perimeter for square is ~p~n", [4*element(2, Form)]);
                circle          -> io:format("perimeter for circle is ~p~n", [2*math:pi()*element(2, Form)]);
                triangle        -> io:format("perimeter for triangle ~p~n", [element(2, Form) + element(3, Form) + element(4, Form)])
        end.
~             
当我跑的时候,我会

38> c("mathStuff.erl").              
{ok,mathStuff}
39> mathStuff:perimeter({circle, 2}).
perimeter for circle is 12.566370614359172
ok
40> mathStuff:perimeter({rectangle, 2}).
** exception error: no case clause matching rectangle
     in function  mathStuff:perimeter/1 (mathStuff.erl, line 5)
41> mathStuff:perimeter({square, 2}).   
perimeter for square is 8
ok
42> mathStuff:perimeter({traingle, 1, 2, 3}).
** exception error: no case clause matching traingle
     in function  mathStuff:perimeter/1 (mathStuff.erl, line 5)
43> mathStuff:perimeter({triangle, 1, 2, 3}).
perimeter for triangle 6
ok
但这是不正确的,因为我也可以这样做

44> mathStuff:perimeter({triangle, 1, 2, 3, 4}).
perimeter for triangle 6
ok
45> 

解决此问题的更好方法是什么,如何更具体地说明类型和参数?

第一个错误的原因是您在
案例中没有匹配
矩形
。。。结束
表达式,因此它无法匹配任何内容。与大多数命令式语言不同,函数式语言中的
case
表达式通常需要至少匹配一个子句——否则,表达式的计算值应该是多少

解决此问题的一种更为惯用的方法是在函数头部,如下所示:

perimeter({square, Side}) ->
    io:format("perimeter for square is ~p~n", [4*Side]);
...
perimeter({triangle, A, B, C}) ->
    io:format("perimeter for triangle ~p~n", [A + B + C]).
请注意,函数子句是使用
分隔的
,最后一个子句以
结尾

本质上,Erlang允许您使用模式匹配来“解包”元组,而不是使用
element/2
从元组中手动选择字段。在我看来,这是将函数语言与代数数据类型结合使用的最大好处之一

顺便说一句,即使对于像
periment({triangle,1,2,3,4})
这样的错误调用,也能得到正确结果的原因是您没有使用模式匹配,而是手动选择元组的相关字段。你从未检查过元组是否太长!模式匹配作为副作用执行一种输入验证,因为表达式如下:

{A, B, C} = {1, 2, 3, 4}

肯定会因匹配错误而失败。

谢谢@Martin,这是理解模式匹配的关键。
{A, B, C} = {1, 2, 3, 4}