第二节 模块与函数(下)

简单列表处理

  上一节我们重点介绍了fun,现在我们继续编写sum和map,来改进我们之前实现的total总和的计算.新建一个mylists.erl

1 -module (mylists).
2 -export ([sum/1]).
3 
4 sum([H | T])    ->    H + sum(T);
5 sum([])            ->    0.

  然后在shell上执行.

  1> L = [1,3,10].
  [1,3,10]
  2> mylists:sum(L).
  14

  然后我们在原有的lists上增加一个map的方法.

1 -module (mylists).
2 -export ([sum/1,map/2]).
3 
4 sum([H | T])    ->    H + sum(T);
5 sum([])            ->    0.
6 
7 map(_, [])        ->    [];
8 map(F, [H | T])    ->    [F(H) | map(F, T)].

  运行结果如下:

  1> L = [1,2,3,4,5].
  [1,2,3,4,5]
  2> mylists:map(fun(X) -> 2*X end, L).
  [2,4,6,8,10]
  3> mylists:map(fun(X) -> X*X end, L).
  [1,4,9,16,25]

  现在我们已经了解了sum和map,我们准备用这个来写shop2.erl

1 -module (shop2).
2 -export ([total/1]).
3 -import (lists, [map/2, sum/1]).
4 
5 total(L)    ->    sum(map(fun({What, N})    ->    shop:cost(What) * N end, L)).

  运行后结果是:

  1> L = [1,2,3,4,5].
  [1,2,3,4,5]
  2> mylists:map(fun(X) -> 2*X end, L).
  [2,4,6,8,10]
  3> mylists:map(fun(X) -> X*X end, L).
  [1,4,9,16,25]

   -import和-export的用法:

  -import(lists, [map/2,sum/1])声明的意思是map/2函数从lists模块里导入的.

  -export([total/1])声明的意思是total/1函数可以在shop2模块之外调用.只有从一个模块里导出的函数才能在该模块之外调用.

列表推导

  列表推导是无需使用fun,map或filter就能创建列表的表达式.它让程序变得更短,更容易理解.

  以前我们是用lists:map来实现的

  1> L = [1,2,3,4,5].
  [1,2,3,4,5]
  2> lists:map(fun(X) -> 2*X end, L).
  [2,4,6,8,10]

  现在我们看看用列表推导是怎么实现的:

  3> [2*X || X <- L].
  [2,4,6,8,10]

  [ F(X) || X <- L]标记的意思是"由F(X)组成的列表(X从列表L中提取)"

  请注意,||符号右边的X是一个模式,用于匹配列表L里面的各个元素.左侧的2*X则是一个构造器.

  最后我们给shop2.erl改成列表推导的方式

  total(L)  ->

    lists:sum([shop:cost(A)*B||{A,B} <- L]).

  列表推导最常规的形式是这种表达式:[X || Qualifier1, Qualifier2, ...] X是任意一条表达式,后面的限定符可以是生成器,位串生成器或过滤器.

    1.生成器的写法Pattern <- ListExpr,其中的ListExp必须是一个能够得出列表的表达式.

    2.位串生成器的写法是BitStringPattern <= BitStringExpr,其中的BitStringExpr必须是一个能够得出位串的表达式.

    3.过滤器既可以是判断函数,也可以是布尔表达式. [X || {a, X} <- [{a,1},{b,2},{c,3},{a,4},hello,"WoW"]].执行结果就是[1,4]

内置函数

  内置函数简称BIF,是那些作为erlang语言定义一部分的函数.

关卡

  关卡是一种结构,可以用它来增加模式匹配的使用.

case和if表达式

  case的语法如下:

  case Expression of

    Pattern1 [when Guard1]  -> Expr_seq1;

    Pattern2 [when Guard2]  -> Expr_seq2;

    ......

  end

  erlang还提供了第二种条件表达式if:

  if

    Guard1 ->

      Expr_seq1;

    

    Guard2 ->

      Expr_seq2;

    ...

  end

转载于:https://www.cnblogs.com/malkin/p/4907402.html

猜你喜欢

转载自blog.csdn.net/weixin_34167043/article/details/94607734