美文网首页Erlang
Hello Erlang!

Hello Erlang!

作者: current | 来源:发表于2016-01-02 02:33 被阅读214次

    本系列文章是《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语言在编写传统顺序程序时的用法。

    相关文章

      网友评论

        本文标题:Hello Erlang!

        本文链接:https://www.haomeiwen.com/subject/wkjwhttx.html