Erlang入门教程 - 9 更复杂的例子

racaljkracaljk

现在给出一个更复杂的例子总结你到目前为止学到的东西。假设你现在有一个世界各城市的温度的列表。列表中有一些城市用的华氏度,有一些用的摄氏度。首先让我们把他们全部转化为摄氏度,然后漂亮的输出这些数据。

%% This module is in file tut5.erl

-module(tut5).
-export([format_temps/1]).

%% Only this function is exported
format_temps([])->                        % No output for an empty list
    ok;
format_temps([City | Rest]) ->
    print_temp(convert_to_celsius(City)),
    format_temps(Rest).

convert_to_celsius({Name, {c, Temp}}) ->  % No conversion needed
    {Name, {c, Temp}};
convert_to_celsius({Name, {f, Temp}}) ->  % Do the conversion
    {Name, {c, (Temp - 32) * 5 / 9}}.

print_temp({Name, {c, Temp}}) ->
    io:format("~-15w ~w c~n", [Name, Temp]).


35> c(tut5).
{ok,tut5}
36> tut5:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},
{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
moscow          -10 c
cape_town       21.11111111111111 c
stockholm       -4 c
paris           -2.2222222222222223 c
london          2.2222222222222223 c
ok

在说明程序是如何运行之前,注意代码中的注释。Erlang的注释以%字符开头直到行末。同时也要注意-export([format_temps/1]). 只包含format_temps/1函数,其他函数都是局部函数,它们在tut5模块外面不可见。

还要注意在shell中测试程序的时候,如果一行太长就展开成两行。

当初次调用format_temps时,City 绑定值{moscow,{c,-10}},Rest绑定列表剩余部分。所以调用的是print_temp(convert_to_celsius({moscow,{c,-10}}))。

这个函数调用把convert_to_celsius({moscow,{c,-10}})的结果传递给print_temp 。当像这样函数嵌套调用时,执行顺序是从里到外。也就是说,convert_to_celsius({moscow,{c,-10}})先被求值,然后print_temp({moscow,{c,-10}})再被求值。函数convert_to_celsius的工作类似于前面例子的convert_length。

print_temp简单的调用io:format。注意~-15w表示在左边输出15个空白之后再输出占位符w实际表示的值。

现在再对列表的剩余部分使用format_temps(Rest)。它所做的事类似于其他语言中的循环结构。(是的,这是递归,但是别担心)。所以同样的format_temps再次被调用。这时City的值绑定为{cape_town,{f,70}},如此反复直至列表为空,匹配第一个clause即format_temps([])。这个clause简单的返回原子ok,程序结束。

文章被以下专栏收录
还没有评论
推荐阅读