Hello Erlang!

本系列文章是《Programming Erlang》的学习笔记

Erlang是什么

Erlang是由Ericsson开发的一种面向并发环境的函数式编程语言,
Erlang的并发性是语言虚拟机支持的,不依赖于OS。

Getting Stared

Erlang是面向并发环境的编程语言,一个Erlang程序是由多个并行的进程构成的。进程执行模块中定义的函数。一个erl文件包含一个模块,编译后的erl文件就可以在shell中直接执行了。

-module(hello).
-export([start/0]).

% Hello erlang
start() ->
    io:format("Hello Erlang!~n").

进入Erlang Shell(erl),就可以运行这个模块了

使用c(hello).编译hello模块使用hello:start().调用start函数,即可看见运行结果

$ erl
1> c(hello).
{ok, hello}
2> hello:start().
Hello Erlang~
ok
3> halt().
$

这是一个最简单的Erlang模块,我们可以通过这个模块学习一下Erlang的基本语法。

  • 不难发现,所以Erlang语句都以.结尾,一个Erlang语句以.+空白结束,空白可以是换行符,空格,tab,等等
  • -module(hello).声明了一个名为hello的模块
  • -export([start/0]).是这个模块的导出函数列表,声明了可以在模块外部调用的函数列表,start/0表示start函数有0个参数
  • start() -> io:format("Hello Erlang!~n").是start函数的定义,io是erlang系统提供的模块,format是io模块导出的一个函数。因此,Erlang中调用函数的基本模式即为<module>:<function>(params).

Getting little sophisticated

Hello Erlang模块阐述了一个最基本的Erlang模块,和所有Hello World!程序一样,这并没有什么卵用。我们需要一个更复杂的程序来展示Erlang的基本编程模式。

%file_server.erl
-module(file_server).
-export([start/1, loop/1]).

start(Dir) ->
    spawn(file_server, loop, [Dir]).

loop(Dir) ->
    receive
        {Client, list_dir} ->
            Client ! {self(), file:list_dir(Dir)};
        {Client, {get_file, File}} ->
            Full = filename:join(Dir, File),
            Client ! {self(), file:read_file(Full)};
        {Client, {put_file, File, Content}} ->
            Full = filename:join(Dir, File),
            Client ! {self(), file:write_file(Full, Content)}
    end,
    loop(Dir).
  • 原子和变量,Erlang中变量以大写字母开头,小写字母开头的名称被称为原子,原子不是变量,而是符号常量,file_server程序中,list_dir,get_file,put_file都是原子而不是变量,模块名也是原子

  • spawn函数用于启动一个进程,并返回一个进程标识符。基本模式为spawn(<Module>, <Function>, [params])

  • self()获取当前进程的pid,erlang进程间通信依赖于pid

  • !用于向另一个进程发送消息,Erlang对现实的建模是通过这种轻量的进程间通信实现的,进程间交互使用消息。语法为<pid> ! <Message>

  • 接收消息,仅仅有发送消息是不够的,还需要接收消息的语法来完成基于消息的进程间通信,接受消息的语法如下。

    receive
        {From ,Message} ->
            Handle the message
    

From记录了消息的来源,Message是消息本身,后续是消息的处理逻辑

  • 多种消息的模式匹配,file_server的代码中可以看见,receive部分有多种模式,不同消息会进入到不同的处理代码中,于是这儿的模式是这样的。

    receive
        Parttern1 ->
            Actions1;
        Parttern2 ->
            Actions2
    %模式之间以;分隔,最后一种模式后面不能写;
    
  • 循环,Erlang是一种函数是编程语言,这意味着其逻辑结构是由一系列的函数演算构成的,和其他函数式语言类似,Erlang没有专门的循环语法,因此循环是通过递归实现的。file_server的代码中可以看见loop函数最后递归调用了自己。递归代码总会有递归栈占用过大的问题,编写成尾递归可以借由编译器的尾递归优化解决这一问题。

上述内容已经涵盖了erlang的基本知识,可以继续写出下面的file_client模块

%file_client.erl
-module(file_client).
-export([ls/1, get_file/2, put_file/3]).

ls(Server) ->
    Server ! {self(), list_dir},
    receive
        {Server, FileList} ->
            FileList
    end.

get_file(Server, File) ->
    Server ! {self(), {get_file, File}},
    receive
        {Server, Content} ->
            Content
    end.

put_file(Server, File, Content) ->
    Server ! {self(), put_file, File, Content}},
    receive
        {Server, Result} ->
            Result
    end.

file_client.el中没有引入新的内容,在shell中运行即可看见运行结果

$ erl
1> c(file_server).
{ok, file_server}
2> c(file_client).
{ok, file_client}
3> FS = file_server:start(".").
<0.45.0> 这是FS这个进程的pid
4> file_client:ls(FS).
{ok,["file_client.beam","file_client.erl",
     "file_server.beam","file_server.erl","hello.erl"]}
5> file_client:get_file(FS, "hello.erl").
{ok,<<"-module(hello).\n-export([start/0]).\n\nstart() ->\n    io:format(\"Hello World!~n\").\n">>}
6> file_client:put_file(FS, "haha", "hehe").
ok
7> file_client:ls(FS).
{ok,["afile_client.beam","afile_client.erl",
     "afile_server.beam","afile_server.erl","haha","hello.erl"]}
8> file_client:get_file(FS, "haha").
{ok,<<"hehe">>}

上述的file_server,file_client,涵盖了Erlang的基本语法,模式。下一篇文章会讲述Erlang语言在编写传统顺序程序时的用法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容