`
dxm1986
  • 浏览: 434283 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

erlang入门笔记

阅读更多

erlang入门笔记

2008-06-20

版权声明 :转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://cbkid.blogbus.com/logs/23258709.html

1.1.2  其它方面

文章省略了以下几个方面:

● 参考

● 本地错误处理(cache/throw)

● 单向连接( 显示器)

● 二进制数据处理

● 列表相关

● 与外界如何通信,以及/ 或者port 其它语言开发的软件。当然,有一些向导中会单

独讲解这个问题。< 互操作向导>

● 涉及到的极少数Erlang( 如,文件处理)

● 关于OTP 的问题完全被跳过,关于Mnesia 数据库的信息在结论中也被省略。

  Erlang 中的哈杀表。

● 运行时改变代码。


1.2.2  模块和函数

Erlang 程序写在文件中。每个文件都包含一个Erlang 模块(Module)


文件名tut.erl 这一点很重要,同时需要确定文件与erl 在同一个目录下.


{ok,tut} 告诉你编译成功。如果它提示"error" ,你可能在输入文本的时候出错,并而错

误信息可能会给你一些有关于如何纠正错误的想法,依此你可以改变你的代码,重新再试。


现在让我们运行这个程序。

4> tut:double(10).


Erlang 程序写在文件中。每个文件都包含一个

Erlang 模块(Module) 。在文件中的第一行,就告诉我们模块的名称(See the

chapter "Modules" in the Erlang Reference Manual)


-module(tut).

这告诉我们模块的名称是tut 。注意本行结尾的"." 。存放模块代码的文件的名字,也必须

和模块同名但以".erl" 做为扩展名。。当我们使用另

一个模块的函数,我们使用语法,模块名: 函数名( 参数) 。所以

4> tut:double(10).

意味着我们调用tut 模块中的double 函数,并使用"10" 做为参数。


-export([double/1]).

说明tut 模块包含一个名称为double 的函数,并且带有一个参数( 在我们的例子中为X)

并而这个函数可以在tut 模块以外被调用。


一个数字的阶乘( 如:4 的阶乘是4*3*2*1) 。在名为

tut1.erl 中输入下面的代码。

-module(tut1).

-export([fac/1]).

fac(1) ->

1;

fac(N) ->

N * fac(N - 1).


第一部分:

fac(1) ->

1;

说明1 的阶乘是1 。注意我们以一个";" 结束这一部分,这说明这个函数没有结束。第二部

分:

fac(N) ->

N * fac(N - 1).

说明N 的阶乘是,NN - 1 的阶乘的乘积(N! = N * (N - 1)!) 。注意这部分

"." 结束,以说明本函数没有其它部分了。


-export([fac/1, mult/2]).

mult(X, Y) ->

X * Y.

注意,我们同时也扩展了-export 行,并给于它关于另一个带有两个参数的函数信息。


变量首字母必须是大写.


1.2.3  元子(Atoms)

元子是在Erlang 中的另一个数据类型。元子以小写字母开头.

元子只是一个简单的名字,其它什么都不是。他们不像变量可以带有一个值。


1.2.4  元组

元组以"{""}" 括起来的。不过元组可以有很多部分,我们想要多就都可以。

例如:

{inch, X} {moscow, {c, -10}}

一组元组有一个固定的大小。我们称元组中的东西为‘元素’。所以在元组{moscow,{c,-

10}} 中,元素1moscow ,元素2{c, -10}


1.2.5  列表

列表在Erlang 中被括在"[""]" 里。

Erlang 可允许分成多行,不过,不可以在元子或整数中间的某部分来分。

一个很有用的遍历列表的方法是使用"|"

[First |TheRest]= [1,2,3,4,5]

我们使用| 来分隔列表中的第一个元素和后续的元素。


[E1, E2 | R] = [1,2,3,4,5,6,7]

这里的| 是用来得到前两个元素。当然,如果我们试着从列表中得到比列表中定义的元素个数更多的元素的话,我们会得到一个错误。

我们通常所说的使用元组,在其它的编程语言中,我们可能会叫做“记录”或“结构体”。我们使用列表( 我们在其它编程语言中所什么的“链表”)


Erlang 并没有字符串类型,取而代之我们可以提供一个由ASCII 字符组成的列表。


1.2.6  标准模块及用户手册

io:format/2 函数自身返回一个元子ok ,注释以% 开始,直到本行结束。同时也要注意-export([format_temps/1]). 一行只包含format_temps/1 函数,另一个函数是局部(local) 函数,他们无法被tut5 模块以外的东西访问。


1.2.9  变量的匹配、守卫和作用域

首先注意我们这里有两个同名的函数list_max 。虽然每个都带有不同数据的参数。在Erlang 这些都会被认为是完全不同的函数。

我们需要通过“名称/ 参数数量”区分这些我们 写的函数,比如在这里是list_max/1list_max/2


-> 之前的特定字符,表示--我们只会在这个特定的条件满足的时候, 才会执行函数的这个部分。我们叫这种类型的测试,叫守卫(guard) 。如果守卫不是‘真’  ( 我们称它为守卫失败) ,我们会尝试执行函数的下一个部分。这种情况下如果Head 不大于Result_so_far 的话,它必定是小于等于它,所以我们在下一部分中,不需要再使用守卫。一些守卫中常见的操作符有<  小于,>  大于,== 等于,>=  大于等于,=<  小于等于,/=  不等于。


Result_so_far 给赋了很多值。那是因为,我们每次调用list_max/2 的时候,我 们建立了一个新的作用域,Result_so_far 在这个作用域中,都会被认为是完全不同的变 量。

另一个建立和给一个变量赋值的方法是使用  = 。如果我写M = 5 ,那么一个名为M 的变量 会被创建,并赋于5 这个值。如果在同一下作用域下,当我写M = 6 ,它就会发生错误。


匹配操作符在通过一组元素创建新变量的时候很有用。

{X, Y} = {paris, {f, 28}}

这里我们看到X 的值被赋于paris ,而Y{f,28}


1.2.10  更多关于列表

| 也可以用来在列表的头部添加元素:

模块lists 包含了很多函数用于维护列表,例如反转列表。所以在我们写一个列表函数之 前,最好先看一下是否在库中已经存在了这样一个函数。



1.2.11 IfCase

if

Condition 1 ->

Action 1;

Condition 2 ->

Action 2;

Condition 3 ->

Action 3;

Condition 4 ->

Action 4

end

注意,在结尾没有";" !条件(Conditions) 和守卫一样,测试成功或是失败。Erlang 会 从最顶上开始向下,直到找到一个成功的条件为止,并执行行条件下面的动作,并且乎略掉 其后面它的条件。如果没有条件匹配,会发生一个运行时(run-time) 错误。元子true 在条件中表示真,它常常被放在条件层,表示如果没有匹配的条件的话,应该做什么动作。


convert_length(Length) ->

case Length of

{centimeter, X} ->

{inch, X / 2.54};

{inch, Y} ->

{centimeter, Y * 2.54}

end.

注意,caseif 都有返回值,即,在上面的例子中case 返回{inch,X/2.54}  {centimeter,Y*2.54}case 的行为也可以使用守卫来代替。


1.2.12  内建函数(BIFs)

内建函数(BIFs) 是一个因为某原因被内嵌在Erlang 虚拟机中的函数。BIFs 经常是一些 在Erlang 上无法实现的功能,或在Erlang 下实现起来效率不高的东西。有些BIFs 可以 直接使用函数的名字,他们默认是属于erlang 模块下的函数。比如trunc 函数,和  erlang:trunc 调用是等同的。


只有很少一部分的内建函数,可以于用守卫,你也无 法在守卫中使用你自己定义的函数。

(see the chapter "Guard Sequences"(http://www.erlang.org/doc/reference_manual/expressions.html) in the Erlang Reference Manual)


1.2.13  复杂函数


convert_to_c 函数,和以前定义的一样,不过我们把它做为一个带入函数来用:  lists:map(fun convert_to_c/1, List)


当我们使用一个要别处定义的fun 函数的话,我们可以能过函数名/ 参数个数,来区别。


sort 函数中,我们使用的fun 函数: fun({_, {c, Temp1}}, {_, {c, Temp2}}) -> Temp1 < Temp2 end,

这里,我们介绍匿名变量”_” 。这是一个简单化的,用于一个将得到值的变量,并且我们还 需要丢弃这个值的情况下。它可以用在任何合适的场合中,不只在fun 中使用。Temp1 < Temp2 返回true 如果Temp1 小于Temp2


1.3  并行编程

1.3.1  进程

并发,我们的意思是一种可以处理掌握若干线程同时执行这样的程序。

”进程”经常指线程间没有共享数据,”线程”指他们之间,有共享的数据或共享内存区

Erlang 内建函数spawn 被用于建立一个新的进程:spawn( 模块,  导出的函数,  参数列 表)

spawn 返回一个进程ID ,或pid ,即一个进程的唯一标识。所以<0.63.0>spawn 函数 的pid ,即进程ID


1.3.2  信息传递


receive 构造用于允许进程等待来自其它进程的消息。它的格式是:

receive

pattern1 ->

actions1;

pattern2 ->

actions2;

....

patternN

actionsN

end.

注意,在结尾没有”;”

Erlang 进程间的消息是一个有效的Erlang 字串,即,它们可以是列表、元组、整数、 元子、pid 等等。


每个进程对于它收到的消息,有一个自己的输入队列。新的消息会放在队列的尾部。当一个 进程执行了一个receive ,队列中第一个与匹配条件一致的消息就会从队列中移除,并匹 配的动作会执行。


如果第一个匹配试没有被匹配的话,第二个就会被检验,如果与队列中移除的条件匹配了的 话,相对于第二个式子中的运作会被执行。第三个也依次类推。如果没有匹配的话,那么第 一个消息就会被放回队列中,并用第二个消息来做对应的操作。如果第二个消息匹配的话, 相应的动作就会被执行,并把第二个消息从队列中移除( 并保留第一个消息和其它的消息在 队列中) 。如果第二个消息也不匹配,我们会试着用第三个消息,直到达到队列尾。如果到 达到队列尾部,进程就会阻塞( 中止执行) 并等待,直到一个新的消息被收到,上面的过程 重复。


注意,”!” 是如何发送消息的,以及”!” 的句法:

Pid ! Message

即,Message( 任何东西) 被发到给了标识为Pid 的进程。


Pong_PID ! {ping, self()},

self() 返回当前自在运行的进程ID ,在这里是”ping” 的进程ID


1.3.3  进程名称注册

有些时候进程 可能需要知道每一个与它不相关的,启动的进程的标识。

这是由register 这个内建函数完成的:

register(some_atom, Pid)


1.3.4  分布式编程

分布式Erlang 的实现,提供了一个基本 的安全机制以防止来自其它计算机的非授权的访问(*manual*)


Erlang 系统要想互相通 信,必需要相同的magic cookie 。最简单的获取它的方法是在你的每台需要Erlang 通 信的机器中的home 文件夹中建立一个.erlang.cookie 的文件(Windows 系统中,  home 文件夹由$HOME 环境变量指定 - 你可能需要首先设定它。在LinuxUnix 系统 中,你可以忽略这一步,只需要简单的在你用户home 文件夹中,建立.erlang.cookie  就可以了).erlang.cookie 文件中需要包含相同的元子字串。如LinuxUnix 系统

中:

$ cd

$ cat > .erlang.cookie

this_is_very_secret

$ chmod 400 .erlang.cookie

上面的chmod 使.erlang.cookie 文件只可以被它的所有者访问。这是必需的。


当你启动一个需要与其它机器上的Erlang 系统交互的一个Erlang 系统时,你必须给它一 个名字,如:

erl -sname my_name

如果你希望体验一下分布式Erlang ,可是你 只有一机计算机的话,你只需要启动两个独立的Erlang 系统在同一台机器上,并给他们不 同的名字就可以了。每一个运行于计算机上的Erlang 系统,被称为一个Erlang 节点。


( 注意:erl -sname  假设所有节点都在同一个IP 域下,如果我们想要使用其它IP 域上

的节点,我们使用-name 代替,并而需要给出完全的IP 地址


Erlangpid 已经包 含它了有关于进程运行的相关信息,所以你只要知道pid ,”!” 就可以用于发送消息,无论 目的地是在同一个节点上,还是其它节点上。


不同的是,我们如何把消息发送到另一个节点上注册的进程中:  {pong, Pong_Node} ! {ping, self()},  我们使用元组{regiester_name, node_name} 代替 注册名。


一个Erlang 进程理论上将一直运行,直到收到不需要的信息。之所以我说“理论上”因为  Erlang 系统与活动进程运享CPU 时间。


当没有事可做的时候,一个进程会终止,即,最后一个函数被调用,并返回一个值,而且不 再调用其它函数了。另一个中止进程的方法是使用exit/1exit/1 的参数有特定的含意, 我们后面再说。


内建函数whereis(RegisteredName) 检测如果一个注册的进程名称叫  RegisteredName 存在,如果存在,返回pid 。否则返回undefined


1.4 健壮性(Robustness  鲁棒性)

  1. 超时(Timeouts)

    超时设 这段代码 中:

pong() ->

receive

{ ping ,  Ping_PID }  ->

io:format( " Pong received ping ~ n ",  []) ,

Ping_PID  !  pong ,

pong()

after 5000 ->

io:format( " Pong timed out ~ n ",  [])

end.

进入 receive 代码段 时, 超时 (after 5000)  如果接 了消 { ping , Ping_PID } 超时将 ,如果 该消 息, 在 5000 毫秒 之后,超时 代码段 作将 行。 after 语句必须 receive 代码段 的最后一个匹配 件。  receive 代码段 中的其匹配 义优 处理。  当然 ,我 们也 可以使用一个 一个 数的函数 超时的设 定值 after pong_timeout() 



  1. 错误处理

一个进程如果使用 exit(normal) 退 行完所有的 代码然 退 出称 (normal) 退 .

一个进程如果发 生了运 行时错误 ( 例如  0 ,错误的匹配, 试图调 用一个不 在的函数 . 错误而 结束   也就 (abnormal) 退 出。

进程 通过调 link(Other_Pid) ( * manual * ) 立自 Other_Pid 进程的 双向 接。  一个进程中 的时 ,将 给每 一个 它建 立了 接的进程发 一个信 (signal) 个信 号包含了 者的 pid 和进程 结束 的原

你可以将一个 (transaction) 及到的所有进程 接在一 , 如果其中的一个进程 常退 出,所有的 该事 中的进程将 全部

函数 spawn_link 在完成 spawn 函数 能的 时建 立了 一个 建的进程的


可以 一个进程接 常退 出信 时的缺 省退 出行   时所有的信 号都 被转换 成一个

分享到:
评论

相关推荐

    Erlang入门

    **Erlang入门** Erlang是一种面向并发的、函数式编程语言,由瑞典电信设备制造商Ericsson在1986年开发,主要用于构建高度可靠和可扩展的分布式系统。这本书"Introducing Erlang"引领读者踏入这个独特的编程世界,...

    erlang 学习笔记1

    【标题】"Erlang 学习笔记1" 在深入探讨Erlang这一强大的并发编程语言之前,我们先来理解一下Erlang的基本概念。Erlang是由瑞典电信设备制造商Ericsson开发的一种函数式编程语言,它最初设计的目的是为了处理分布式...

    erlang开发入门教程

    erlang是爱立信开发的程序开发语言,融合了函数式编程与面向对象编程,并行处理内建与程序语言内部,特别适合创建并发行、容错性、分布性要求比较高的软实时系统,掌握它程序员必备的一种编程技能,与它相似的语言...

    erlang入门学习经典资料(很不错)

    ### Erlang 入门学习经典资料解析 #### Erlang 的神秘与起源 Erlang,作为一门相对小众但极具特色的编程语言,自问世以来便伴随着一种神秘的气息。这种神秘感不仅源于它独特的编程范式——函数式编程,还在于其...

    Erlang入门:构建application练习2

    Erlang是一种面向并发的、函数式编程语言,由瑞典电信设备制造商Ericsson开发,用于构建高可用性、分布式和实时系统。在本教程中,我们将深入探讨如何使用Erlang构建一个名为"Application"的基本应用程序,这在...

    erlang入门级练习:LeetCode OJ问题的部分erlang 源码

    我自己在新学erlang,在LeetCode OJ上找了题目练习,题目很适合新手熟悉语言,但是LeetCode OJ里面只有几门主流语言的答案,下面是已完成的erlang源代码,后续有空再做其他问题续传,题目包含:(源码开头都有题目...

    Erlang入门:构建application练习5(监督树)

    在这个"Erlang入门:构建application练习5(监督树)"中,我们将探讨如何构建一个包含监督树的应用,这是Erlang OTP(开放电信平台)设计模式中的核心部分。 监督树是Erlang OTP设计原则的重要组成部分,它用于管理...

    erlang 入门练习

    本文将通过"erlang 入门练习"的案例,探讨Erlang的基础知识和应用。 首先,让我们从`client.erl`这个文件名入手。在Erlang中,`.erl`文件是源代码文件,包含了Erlang的模块定义和函数实现。`client`可能表示一个...

    Erlang入门ppt

    这份名为"Erlang入门ppt"的资料是英文版的,但提供了深入理解Erlang语言的基础。 在20世纪90年代初,软件项目成功率低、大型项目失败率高是一个普遍问题。研究指出,16%的软件项目成功,53%虽然运行但未达到预期,...

    Erlang入门:构建application练习4(进程link的作用)

    在Erlang编程语言中,进程是其核心特性之一,它们是并发执行的实体,类似于其他语言中的线程。在Erlang中,进程间通信(IPC)是通过消息传递来实现的,而`link`机制是这个通信模型中非常重要的一部分。本教程将通过...

    erlang学习笔记

    ### Erlang学习笔记:深入解析Erlang编程与系统管理 #### 1. Erlang编程基础与资源 在深入探讨Erlang编程之前,我们首先需要了解一些基础资源和学习资料。Erlang官方网站([www.erlang.org](http://www.erlang.org...

    Erlang初级入门(英文pdf)

    ### Erlang基础知识与特性 #### 一、Erlang简介 Erlang是一种专为处理大规模并发活动设计的编程语言,由瑞典电信设备制造商爱立信的计算机科学实验室(Computer Science Laboratory, CSLab)开发。该语言的目标是...

    erlang程序设计与入门

    **Erlang程序设计与入门** ...通过阅读《Erlang入门手册》和《Erlang程序设计》这两本书,你可以深入了解Erlang的基础知识、编程技巧以及最佳实践,从而在函数式编程和并发系统的世界里游刃有余。

    erlang 笔记

    ### Erlang程序设计知识点概述 #### 1. Erlang基础语法与函数定义 - **模块定义**: 在Erlang中,所有的代码都包含在模块之中。例如:`-module(tut).` 定义了一个名为`tut`的模块。 - **函数定义与导出**: 函数定义...

    erlang编程指南

    erlang编程语言圣经 erlang从业人员的必备书籍 erlang语言开发入门

    erlang资源

    这个“erlang资源”包含两本PDF书籍——《Erlang并发编程》和《Erlang入门手册》,它们是深入理解和学习Erlang语言的关键资料。 《Erlang并发编程》这本书可能涵盖了以下知识点: 1. **并发模型**:Erlang的并发...

Global site tag (gtag.js) - Google Analytics