`
cnDenis
  • 浏览: 99406 次
  • 来自: 广州
社区版块
存档分类
最新评论

初识Erlang,Hello World(2)

阅读更多

初识Erlang,Hello World(2)

by cnDenis 2013年3月12日

昨天费了老大劲终于把Hello World打出来了,今天我们继续。

说N遍Hello World,递归的使用

Hello World说一遍怎么够呢,说N遍吧。代码如下:

-module(helloworld).
-export([hw3/1]).
% 打印N遍Hello world
hw3(N) when N > 0 -> 
    io:format("Hello World ~n"),
    hw3(N-1);

hw3(0) -> ok.

这有什么好坑的呢:

hw3(N) when N > 0 ->

when后面是一个guard,仅在它为true时函数会被执行。

保护元所能使用的语句是受限的,不能用自定义的函数。

io:format("Hello World ~n"),
hw3(N-1);

这一个函数体有多条语句,中间需要用逗号隔开

hw3(0) -> ok.

hw3/1这个函数有几个函数子句,根据参数的模式识别和when保护元的值来选择使用函数体。

不同的函数体之间使用分号,最后一个末尾使用句点。

啥都不干用什么好呢?stackoverflow 上说用ok. 那就用ok吧。

再说N遍Hello World,使用case

如果不想用多个函数子句的话,可以用case

hw5(N) ->
    case N of
        X when X > 0 -> 
            io:format("Hello World ~n"),
            hw5(N-1);
        0 -> ok
    end.

case的语法是:

case 条件表达式 of ->
    模式1 -> 语句段1;
    模式2 -> 语句段2;
    ....
    模式N -> 语句段N
end

继续一行一行看:

case N of

N是条件表达式,也就是说运行case中的哪一条子句会根据N的值来决定。

只有一个子句会被执行,这点跟C语言不一样。

而且如果全部子句的模式匹配都失败的话,会抛出错误。所以要考虑是否使用catch all的语句。

条件表达式与子句之间是用of来分隔的,注意不要顺手打冒号了。

X when X > 0 ->

模式后面可以接when,也可以不用。

这一行是这么运行的:首先是对X和N进行模式匹配,即X=N,匹配是成功的,因为 变量X没有赋值,所以X绑定到N,然后由于保卫元X>0为true,所以执行该子句。

io:format("Hello World ~n"),
hw5(N-1);

注意模式与语句段之间是用 -> 分开的,中间的case语句段需要以分号结束

0 -> ok

递归结束条件,不可忘记的。最后一个case子句,也就是end之前不需要加标点

end.

case语句需要以end结束,后面这个句点是表示hw5整个函数的结束,不是case语法的一部分

继续说Hello World,使用if

if可以视为没有条件表达式和of的case

hw6(N) ->
    if 
        N > 0 -> 
            io:format("Hello World ~n"),
            hw5(N-1);
        N == 0 ->
            ok
    end.

if的语法格式是:

if
    保护元1 -> 语句1;
    保护元2 -> 语句2;
    .......
    保护元N -> 语句N
end

if会执行第一个保护元为真的语句。

要注意的东西跟case没什么区别,就不啰嗦了。

继续Hello World,使用列表解析

这似乎是最简洁的做法了

hw7(N) ->
    [hw() || _ <- lists:seq(1, N) ].

这句话换相当于Python中的 [hw() for _ in range(1, N + 1)]。

意思是把(1,2,3...N)中的每一个值都装到变量_之后,运行hw()。由于hw中不调用 seq中产生的值,所以拿_这样的一个坑来装。

lists:seq是产生一个连接序列的数组,与Python中的range不同的是,它是既包头又包 尾的,也是就说产生(1,2,3...N)。

继续Hello World,山寨for

Erlang最令人觉得奇怪的是它没有循环语句,不过这不妨碍我们直接山寨一个。

for(I, N, F) when I < N -> 
    F(),
    for(I + 1, N, F);
for(N, N, F) ->
    F().

hw8(N) ->
    for(1, N, fun hw/0).

hw9(N) ->
    for(1, N, fun() -> hw() end).

这个山寨的for用了高阶函数的概念,它的F参数是是一个函数。注意hw8/1hw9/1中 的写法,我碰壁了好久,后来问了程序老大才解决的。

hw8/1是把函数名当参数后用,必须要使用fun关键词,而且要指明函数的目数, 这与Python不一样。Python一个函数名只能绑定一个函数,给出名字就唯一确定了绑定 对象。而Erlang允许同名不同目的函数,所以要指明目数。

hw9/1则是产生一个匿名函数作为参数,注意匿名函数的写法。以fun作为函数名, 其余跟一般函数没什么区别。注意fun后面的括号不要漏掉,即使没有参数。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics