Erlang入门

By AverageJoeWang
 标签:

一.简单笔记

  • 操作符=:变量一旦赋值就不能修改
  • 变量:大写字母开头
  • 原子:小写字母开头

二.编译运行方式

2.1.例子

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

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

2.2.编译与运行方式

#第一种
erl
c(hello).
hello:start().
halt().

#c(hello)命令编译了hello.erl文件里的代码。{ok, hello}的意思是编译成功。现在代
#码已准备好运行了。第2行里执行了hello:start()函数。第3行里停止了Erlang shell。  

#第二种编译方式
erlc hello.erl
erl -noshell -s hello start -s init stop
  • erlc从命令行启动了Erlang编译器。编译器编译了hello.erl里的代码并生成一个名为hello.beam的目标代码文件。
  • erl -noshell ...命令加载了hello模块并执行hello:start()函数。随后,它执行了
  • init:stop()这个表达式终止了Erlang会话。
  • Erlang shell之外运行Erlang编译器(erlc)是编译Erlang代码的首选方式。可以在Erlang shell里编译模块,但要这么做必须首先启动Erlang shell。使用erlc的优点在于自动化。我们可以在rakefilemakefile内运行erlc来自动化构建过程。

三.简单客户端与服务器

3.1.server_s.erl

-module(server_s).
-export([start/1, loop/1]).

start(Dir)->
    spawn(server_s, loop, [Dir]).
%spawn is a function of start a process, like "spawn(<module>, <function>, [params])"

loop(Dir)->
    receive
        %receive message
        {Client, list_dir}->
            Client ! {self(), file:list_dir(Dir)};
        %self() get pid, 
        %"!" send message to  another process,the format is "<pid> ! <Message>"
        {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中变量以大写字母开头,小写字母开头的名称被称为原子,原子不是变量,而是符号常量,server_s程序中,list_dirget_fileput_file都是原子而不是变量,模块名也是原子

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

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

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

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

receive
    {From ,Message} ->
        Handle the message
  • From记录了消息的来源,Message是消息本身,后续是消息的处理逻辑

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

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

3.2.client.erl

-module(client_s).
-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.