注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

ocean's blog

平常心——可以寂寞,但不允许空虚

 
 
 

日志

 
 

接触Erlang  

2009-06-03 17:07:33|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Erlang是一种通用的面向并发的编程语言,它由瑞典电信设备制造商爱立信所辖的CS-Lab开发,目的是创造一种可以应对大规模并发活动的编程语言和运行环境。Erlang问世于1987年,经过十年的发展,于1998年发布开源版本。Erlang是运行于虚拟机的解释性语言,但是现在也包含有乌普萨拉大学高性能Erlang计划(HiPE)开发的本地代码编译器,自R11B-4版本开始,Erlang也开始支持脚本式解释器。在编程范型上,Erlang属于多重范型编程语言,涵盖函数式、并发式及分布式。(维基百科)

Erlang不但是一种编程语言,而且它具有比编程语言更加贴近操作系统的一些特性:并发线程、作业调度、内存管理、分布式、网络化等。据说使用Erlang编写的Yaws Web服务器,其并发性能是apache的15倍!(WOW 15倍!!!!!!!)

Erlang的问题领域
高并发 : 应对超大量的并发活动。
分布式 :系统 可以跨计算机分布运行。
持续服务 : 系统应该能不间断运行许多年。
热升级 : 软件维护 / 升级 应该能在不停止系统的情况下进行。
可靠 :满足苛刻的质量和可靠性需求。包括提供容错功能, 在硬件失灵和软件错误。

还有人提出 Erlang, the next Java ?
我想随着CPU多核化,信息越来越膨胀,服务器承受越来越高的负荷,还加上云计算, 这或许会成为可能。

 

1 Erlang 安装

1.1 二进制包安装
* linux环境
基于debian的系统有相应的二进制包,可以使用命令:
# apt-get install erlang

* Mac OS X环境
Mac用户可以使用MacPorts来安装Erlang预打包版本。

* Windows环境
Windows用户可以从http://www.erlang.org/downlad.html中找到各个版本的下载列表。选择最新版本,下载后,双击安装。

1.2 从源代码安装
这里做ubuntu环境介绍:
$ sudo apt-get build-dep erlang
$ tar -xzf opt_src_xxxx.tar.gz
$ cd opt_src_xxx
$ ./configure
$ make
$ sudo make install
在编译之前,可以使用命令./configure --help来查看配置选项。

1.3 启动shell
shell是一个交互工具。启动shell之后,就可以输入表达式,然后shell返回值。
如果已经安装好了Erlang,那么Erlang shell——erl也就同时安装好了。在操作系统的命令行界面输入erl来启动。(windows用需要修改环境变量PATH,还可以通过菜单 开始/所有程序/Erlang OTP/Erlang来启动)


$ erl
Erlang (BEAM) emulator version 5.5.1[source][async-threads:0][hipe]

Eshell V5.5.1 (abort with ^G)
1> % I'm goingto enter some expressions in the shell ..
1> 20 + 30.
50
2>

shell显的1>代表行号,%代表注释,.代表语句的结束(常常容易忘记),退出shell,按下^G再输Q回车。

注意:不是所有东西都可以输入到shell。不能往shell输入Erlang文件当中的代码。.erl文件中句法形式不是表达式,不能被shell接受。 shell仅仅能够对Erlang表达式求值,除此之外的事情都做不了。也不能在shell输入模块注解。

1.4 简单整数运算
1> 2 + 3 * 4.
14
2> (2 + 3) * 4.
20

Erlang遵守标准算术表达式的法则,并且采用不定长的整数进行算术演算。在Erlang中,整数运算没有误差,因此不用担心溢出。

3> 123457689 * 987654321 .
121933520001524169

4> 16#cafe * 32#sugar. %使用16进制和32进制
1577682511434

1.5 变量
1> X = 123456.
123456

现在就给变量X赋了一值,shell打印出了变量的值

所有的变量都必须以大写字母开头

要查看变量的值,只要输入变量的名字即可。
2> X.
123456
3> X*X*X*X.

当你想再次给X赋上另外一个值的时间,系统会抛出一个错误消息。
4> X = 1234.
** exception error: no match of right hand side value 1234

这是为什么呢?在其他的语言中都是这样的使用的。

* 首先,X不是一个变量,至少不是像JAVA,C中碰到的那种
* 其次,=不是一个赋值操作符。

这是一个让新手犯晕的地方,再深入看一看。

1.5.1 变量不变
Erlang的变量是单一赋值变量。值只能一次性地给定。一个变量如果含有一个被赋予的值,就称为绑字变量,否则称为自由变量。一开始所以的变量都是自由的。

为什么说=又不是一个赋值操作符呢?其实就其本质而言,=是一个模式匹配运算符。

1.5.2 模式匹配

在大多数语言中,=都表示赋值语句。然而,在Erlang中,=表示一个模式匹配操作。Lhs=Rhs实际上是这样一个过程:
对右端求值(Rhs),然后将结果与左端(Lhs)进行模式匹配。

1> X = (2+4).
6
2> Y = 10.
10
3> X = 6.
6
4> X = Y .
** exception error: no match of right hand side value 10
这里要注意下1行和3行。
第一行 X = 2+4,结果为6,第三行 X = 6.并没有出错,是因为X的值本身就为6,所以是可以匹配的。

1.5.3 单一赋值有益于编写质量更高的代码
Erlang里面的变量仅是对值的一个引用,就具体实现来说,一个绑定变量就是一个指针,这个指针指向存放那个值的存储区。而那个值是无法改变的。
不能改变一个变量的值是极为重要的事实。在代码错误的排查中相当常见的一种错误就是,变量被赋了一个错误的值。在这种情下,就需要找出程序从哪儿获得的错误值。如果变量在程序的不同地方多次修改了值,那么要找出哪些修改是错误的是非常困难的。
在Erlang中就不存在这个问题,变量赋值之后永不再变,一旦发现变量出错,就能立刻确定程序之中绑字这个变量的代码,这就是错误产生之处。

1.6 浮点数
1> 5/3.
1.66667
2> 4/2.
2.00000
3> 5 div 3.
1
4> 5 rem 3.
2
5> 4 div 2.
2

" / "永远返回浮点数,因此,4/2的结果是2.0000。div和rem是整数除和取余数。

1.7 原子
在Erlang中,原子用来表示不同的非数字常量值。而且全局有效。
原子是一串以小写字母开头,后跟数字、字母、下划线或@符号的字符。例如:
red, december, cat, meters, yards, joe@somethost以及a_long_name等。
使用单引号引起来的字符也是原子,这样就能使用得原子可以用大写字母作为开头或者包含非数字字符。例如:
'Monday', 'Tuesday', '+', '*'
一个原子的值就是原子自身。

1.8 元组
如果要将多个数据项组成单一实体,就可以使用元组。将若干个以逗号分割的值用一对花括号括起来,就形成了一个元组。
P = {10,45}
元组中的字段没有名字,为了方便记忆,通常可以使用一个原子作为元组的第一个元素来标明这个元组所代表的含义。
1> Person = {persion,
                {name, joe},
                {height, 1.82},
                {footsize, 42},
                {eyecolour, bronw}}.

1.8.1 创建元组
在声明元组时,就自动创建了元组,不再使用它们时,元组随之销毁。Erlang使用垃圾回搜集去收回没有使用的内存。
2> F = {firstName, joe}.
{firstName, joe}
3> L = {lastName, armstrong}.
{lastName, armstrong}
4> P = {person, F, L}
{person, {firstName, joe}, {lastName, armstrong}}

1.8.2 从元组中提取字段值
模式匹配作为Erlang的基础,用来完成很多不同的任务:可以用它从数据结构中提取字段值,在函数中进行流程控制,或者当你向一个进程发送消息时,从并行程序中筛选那些需要处理的消息。
1> Point = {point, 10, 45}.
{point, 10, 45}
若想从Point中提取字段存于X, Y变量中,可以这么做:
2> {point, X, Y} = Point.
{point, 10, 45}
3> X.
10
4> Y.
45
位于等号两边的元组必须含有相同的数量的元素,两边相对应的元素必须绑定相同的值。
如果有一个复杂的元组,那么可以使用相同结构的模式来提取所要的字段值,并且只要在需要提取的字段位置上使用未绑定变量。
例如:
1> Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
{person,{name,{first,joe},{last,armstrong}},{footsize,42}}
现在,要提取个人的姓:
2> {_,{_,{_,Who},_},_} = Person.
3> Who.
joe
" _ "作为占位符,称为匿名变量,与常规变量不同,在同一个模式中的不同地方,各个 _ 所绑字的值不必相同。



1.9 列表
将若干个以逗号分割的值用一对方括号括起来,就形成了一个列表。
1> ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
[{apples, 10}, {pears, 6}, {milk, 3}]

列表之中的各个元素可以有各自不同的类型。
2> [1+7, hello, 2-2, {cost, apple, 30-20},3].
[8, hello, 0, {cost, apple, 10},3]

1.9.1 术语
列表的第一个元素称为列表的头,剩下的就是列表的尾,列表的头可以是任何东西,但是列表的尾通常还是一个列表。
实际上所有的列表处理函数都是从提取列表头开始的。

1.9.2 定义列表
如果T是一个列表,那么[H|T]也是一个列表。这个列表以H为头,T为尾。无论何时,当用[..|T]来构造一个列表时,都应保证T是一个列表。

1.9.3 从列表中提取元素
可以用模式匹配从一个列表中提取元素。[X|Y] = L。这里X,Y是自由变量。

1.10 字符串
严格的讲,Erlang中并没有字符串,字符串实际上就是一个整数列表。用双引号将一串字符括起来就是一个字符串。而且必须是用双引号。
1> Name = "Hello".
"Hello"
这里的Hello实际上意味着一个整数列表 [104, 101, 108, 108, 111]。
只要列表中的所有整数都是可以打印字符,就把这个列表当作字符串来打印。
2> [1,2,3].
[1,2,3]
3> [83, 117, 114, 112, 114, 105, 115, 101].
"Surprise"
4> [1, 83, 117, 114, 112, 114, 105, 115, 101].
[1, 83, 117, 114, 112, 114, 105, 115, 101].
无须死记硬背哪个整数表示哪个一个特定的字符,可以用$符号来表示:
5> $s.
115

1.11 再论模式匹配
Pattern      Term                  Result
{X,abc}   {123,abc}              成功 X → 123
{X,Y,Z}   {222,def,"cat"}        成功 X → 222, Y → def,Z → "cat"
{X,Y}     {333,ghi,"cat"}        失败—元组结构不同
X          true                  成功 X → true
{X,Y,X}   {{abc,12},42,{abc,12}} 成功 X → {abc,12}, Y → 42
{X,Y,X}   {{abc,12},42,true}     失败—X不能同时为{abc, 12}和true
[H|T]     [1,2,3,4,5]            成功 H → 1, T → [2,3,4,5]
[H|T]     "cat"                  成功 H → 99, T → "at"
[A,B,C|T] [a,b,c,d,e,f]          成功 A → a, B → b,C → c, T → [d,e,f]

  评论这张
 
阅读(39)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017