erlang学习备忘

1 辙道辕门 发表于 2014-07-01 21:10:15 +0800 阅览(92) 评论(0)
 
 

erlang是一门函数式语言。它最初是以prolog为蓝本进行改进的。它在可靠性方面有比较明显的优势,并且非常擅长并发。鉴于线程在共享资源时的许多瓶颈,erlang采用轻量级进程的办法来执行并发任务。

可靠性:erlang所要面对的是需要高容错度的应用。因此比起常规的语言,erlang有许多独到的机制来保证这一点。它可以热插拔代码、崩溃时拥有超强的恢复机制。

函数式语言一般来说有以下几点特性:

  1. 程序完全基于函数编写出来,很可能压根就没有对象的概念
  2. 一般来说给定相同输入,会返回相同的值
  3. 函数通常没有副作用,也即:不改变程序的状态
  4. 变量只能赋值一次

实际上erlang也并非100%纯度的函数式语言,因此也有例外。

erl打开erlang的命令行;在erl中执行c(filename). 编译文件。filename可以不加扩展名,但要与文件中声明的module名相同(类似java的公有类必须要等同于文件名)。

-module(module_name).

声明命名空间。

-export([function/argc]).

声明函数/参数数量。

例: haomen.erl

-module(haomen).
-export([loves/1]).
-export([jiecheng/1]).
-export([fib/1]).
-export([print_arg/1]).
-export([get_value/2]).

loves(neko) -> true;
loves(azi) -> true;
loves(_) -> false.


jiecheng(0) -> 1;
jiecheng(N) -> N * jiecheng(N-1).

fib(0) -> 1;
fib(1) -> 1;
fib(N) -> fib(N-1) + fib(N-2).

print_arg(Arg) ->
  case Arg of
    haomen -> "haomenchuqu";
    azi -> "azi daisuki";
    _ -> string:concat("arg is", Arg)
  end.

get_value(Key, HashTable) -> 
  [ V || {K, V}

在erl中执行

c(haomen).

便可编译出.beam格式的字节码。

然后在erl中使用

haomen:fib(5).

的形式就可调用haomen中的函数。

在erlang中,小写字母是原子,大写字母是变量,正如prolog中那样。但变量只能赋值一次,不能重复赋值。

[1,2,3]声明一个列表(数组)。列表是变长、允许不同类型元素、允许相同值、有顺序的。

{1,2,3}声明一个元组。元组是定长的。因此常常用元组来实现散列表。

erlang也可以使用[Head|Tail]这样的语法,甚至[One, Two|Three] = [1,2,3].这样的匹配。这样的话,One和Two分别为1和2,而Three为[3]。

位匹配:

打包:
1> W = 1.
1
2> X=2.
2
3> Y=3.
3
4> Z=4.
4
5> All = <<W:3,X:3,Y:5,Z:5>>.
<<"(d">>

解包:
6> <<A:3,B:3,C:5,D:5>> = All.
<<"(d">>
7> A.
1
8> B.
2
9> C.
3
10> D.
4

 定义函数:

Fun = fun(Arg1, Arg2) -> [Arg1, Arg2] end.

一些有用的函数:

lists:foreach(Fun, List).  %遍历List数组执行Fun

lists:all(Fun, List) . %判断是否所有List的元素都满足Fun。特别地,当list为空时,本函数返回true。

lists:any(Fun,List).  % 判断是否存在List中的元素满足Fun。特别地,当list为空时,本函数返回false。

lists:foldl(Fun, InitValue, List). %其中fun接收两个参数,第一个参数用来处理列表中的元素;第二个参数会被上一次的返回值迭代。

lists:map(Fun,List). %遍历List数组执行Fun,求返回值的集合。即Fun函数在List上的映射

另有一个简便形式: [Fun(X) || X <- List]. 右边可拥有任意数量的子句。

 

 

一个翻译程序示例:

% translate.erl
-module(translate).
-export([loop/0, translate/2]).

loop() ->
  receive
    {From, "hello"} ->
      From ! "konnichiha",
      loop();
    {From, "bye"} ->
      From ! "sayonara",
      loop();
    {From, _} ->
      From ! "wakaranaiyo",
      loop()
  end.
translate(To, Word) ->
  To ! {self(), Word}, % self() 函数获得当前进程Pid
  receive
    Translation -> Translation
  end.

在erl中执行:

1> c(translate).
{ok,translate}
2> Translator = spawn(fun translate:loop/0).

3> translate:translate(Translator,"hello").
"konnichiha"
4> translate:translate(Translator,"bye").  
"sayonara"
5> translate:translate(Translator,"who").    
"wakaranaiyo"

如果是一台远程服务期上的程序,使用:node@server ! message来发送。具体待查。


待续。。。

 
|

评论列表

还没有人评论。
返回