●涉及到的極少數(shù)Erlang" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

erlang入門筆記

系統(tǒng) 2763 0

erlang入門筆記

2008-06-20

版權(quán)聲明 :轉(zhuǎn)載時(shí)請(qǐng)以超鏈接形式標(biāo)明文章原始出處和作者信息及 本聲明
http://cbkid.blogbus.com/logs/23258709.html

1.1.2 ? 其它方面

文章省略了以下幾個(gè)方面:

● 參考

● 本地錯(cuò)誤處理 (cache/throw)

● 單向連接 ( 顯示器 )

● 二進(jìn)制數(shù)據(jù)處理

● 列表相關(guān)

● 與外界如何通信,以及 / 或者 port 其它語言開發(fā)的軟件。當(dāng)然,有一些向?qū)е袝?huì)單

獨(dú)講解這個(gè)問題。 < 互操作向?qū)? >

● 涉及到的極少數(shù) Erlang ( 如,文件處理 )

● 關(guān)于 OTP 的問題完全被跳過,關(guān)于 Mnesia 數(shù)據(jù)庫的信息在結(jié)論中也被省略。

? Erlang 中的哈殺表。

● 運(yùn)行時(shí)改變代碼。


1.2.2 ? 模塊和函數(shù)

Erlang 程序?qū)懺谖募小C總€(gè)文件都包含一個(gè) Erlang 模塊 (Module)


文件名 tut.erl 這一點(diǎn)很重要,同時(shí)需要確定文件與 erl 在同一個(gè)目錄下 .


{ok,tut} 告訴你編譯成功。如果它提示 "error" ,你可能在輸入文本的時(shí)候出錯(cuò),并而錯(cuò)

誤信息可能會(huì)給你一些有關(guān)于如何糾正錯(cuò)誤的想法,依此你可以改變你的代碼,重新再試。


現(xiàn)在讓我們運(yùn)行這個(gè)程序。

4> tut:double(10).


Erlang 程序?qū)懺谖募小C總€(gè)文件都包含一個(gè)

Erlang 模塊 (Module) 。在文件中的第一行,就告訴我們模塊的名稱 (See the

chapter "Modules" in the Erlang Reference Manual)


-module(tut).

這告訴我們模塊的名稱是 tut 。注意本行結(jié)尾的 "." 。存放模塊代碼的文件的名字,也必須

和模塊同名但以 ".erl" 做為擴(kuò)展名。。當(dāng)我們使用另

一個(gè)模塊的函數(shù),我們使用語法,模塊名 : 函數(shù)名 ( 參數(shù) ) 。所以

4> tut:double(10).

意味著我們調(diào)用 tut 模塊中的 double 函數(shù),并使用 "10" 做為參數(shù)。


-export([double/1]).

說明 tut 模塊包含一個(gè)名稱為 double 的函數(shù),并且?guī)в幸粋€(gè)參數(shù) ( 在我們的例子中為 X)

并而這個(gè)函數(shù)可以在 tut 模塊以外被調(diào)用。


一個(gè)數(shù)字的階乘 ( 如: 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 。注意我們以一個(gè) ";" 結(jié)束這一部分,這說明這個(gè)函數(shù)沒有結(jié)束。第二部

分:

fac(N) ->

N * fac(N - 1).

說明 N 的階乘是, N N - 1 的階乘的乘積 (N! = N * (N - 1)!) 。注意這部分

"." 結(jié)束,以說明本函數(shù)沒有其它部分了。


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

mult(X, Y) ->

X * Y.

注意,我們同時(shí)也擴(kuò)展了 -export 行,并給于它關(guān)于另一個(gè)帶有兩個(gè)參數(shù)的函數(shù)信息。


變量首字母必須是大寫 .


1.2.3 ? 元子 (Atoms)

元子是在 Erlang 中的另一個(gè)數(shù)據(jù)類型。元子以小寫字母開頭 .

元子只是一個(gè)簡(jiǎn)單的名字,其它什么都不是。他們不像變量可以帶有一個(gè)值。


1.2.4 ? 元組

元組以 "{" "}" 括起來的。不過元組可以有很多部分,我們想要多就都可以。

例如:

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

一組元組有一個(gè)固定的大小。我們稱元組中的東西為‘元素’。所以在元組 {moscow,{c,-

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


1.2.5 ? 列表

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

Erlang 可允許分成多行,不過,不可以在元子或整數(shù)中間的某部分來分。

一個(gè)很有用的遍歷列表的方法是使用 "|"

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

我們使用 | 來分隔列表中的第一個(gè)元素和后續(xù)的元素。


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

這里的 | 是用來得到前兩個(gè)元素。當(dāng)然,如果我們?cè)囍鴱牧斜碇械玫奖攘斜碇卸x的元素個(gè)數(shù)更多的元素的話,我們會(huì)得到一個(gè)錯(cuò)誤。

我們通常所說的使用元組,在其它的編程語言中,我們可能會(huì)叫做“記錄”或“結(jié)構(gòu)體”。我們使用列表 ( 我們?cè)谄渌幊陶Z言中所什么的“鏈表” )


Erlang 并沒有字符串類型,取而代之我們可以提供一個(gè)由 ASCII 字符組成的列表。


1.2.6 ? 標(biāo)準(zhǔn)模塊及用戶手冊(cè)

io:format/2 函數(shù)自身返回一個(gè)元子 ok ,注釋以 % 開始,直到本行結(jié)束。同時(shí)也要注意 -export([format_temps/1]). 一行只包含 format_temps/1 函數(shù),另一個(gè)函數(shù)是局部 (local) 函數(shù),他們無法被 tut5 模塊以外的東西訪問。


1.2.9 ? 變量的匹配、守衛(wèi)和作用域

首先注意我們這里有兩個(gè)同名的函數(shù) list_max 。雖然每個(gè)都帶有不同數(shù)據(jù)的參數(shù)。在 Erlang 這些都會(huì)被認(rèn)為是完全不同的函數(shù)。

我們需要通過“名稱 / 參數(shù)數(shù)量”區(qū)分這些我們 寫的函數(shù),比如在這里是 list_max/1 list_max/2


-> 之前的特定字符,表示--我們只會(huì)在這個(gè)特定的條件滿足的時(shí)候, 才會(huì)執(zhí)行函數(shù)的這個(gè)部分。我們叫這種類型的測(cè)試,叫守衛(wèi) (guard) 。如果守衛(wèi)不是‘真’ ? ( 我們稱它為守衛(wèi)失敗 ) ,我們會(huì)嘗試執(zhí)行函數(shù)的下一個(gè)部分。這種情況下如果 Head 不大于 Result_so_far 的話,它必定是小于等于它,所以我們?cè)谙乱徊糠种校恍枰偈褂檬匦l(wèi)。一些守衛(wèi)中常見的操作符有 < ? 小于, > ? 大于, == 等于, >= ? 大于等于, =< ? 小于等于, /= ? 不等于。


Result_so_far 給賦了很多值。那是因?yàn)椋覀兠看握{(diào)用 list_max/2 的時(shí)候,我 們建立了一個(gè)新的作用域, Result_so_far 在這個(gè)作用域中,都會(huì)被認(rèn)為是完全不同的變 量。

另一個(gè)建立和給一個(gè)變量賦值的方法是使用 ? = 。如果我寫 M = 5 ,那么一個(gè)名為 M 的變量 會(huì)被創(chuàng)建,并賦于 5 這個(gè)值。如果在同一下作用域下,當(dāng)我寫 M = 6 ,它就會(huì)發(fā)生錯(cuò)誤。


匹配操作符在通過一組元素創(chuàng)建新變量的時(shí)候很有用。

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

這里我們看到 X 的值被賦于 paris ,而 Y {f,28}


1.2.10 ? 更多關(guān)于列表

| 也可以用來在列表的頭部添加元素:

模塊 lists 包含了很多函數(shù)用于維護(hù)列表,例如反轉(zhuǎn)列表。所以在我們寫一個(gè)列表函數(shù)之 前,最好先看一下是否在庫中已經(jīng)存在了這樣一個(gè)函數(shù)。



1.2.11 If Case

if

Condition 1 ->

Action 1;

Condition 2 ->

Action 2;

Condition 3 ->

Action 3;

Condition 4 ->

Action 4

end

注意,在結(jié)尾沒有 ";" !條件 (Conditions) 和守衛(wèi)一樣,測(cè)試成功或是失敗。 Erlang 會(huì) 從最頂上開始向下,直到找到一個(gè)成功的條件為止,并執(zhí)行行條件下面的動(dòng)作,并且乎略掉 其后面它的條件。如果沒有條件匹配,會(huì)發(fā)生一個(gè)運(yùn)行時(shí) (run-time) 錯(cuò)誤。元子 true 在條件中表示真,它常常被放在條件層,表示如果沒有匹配的條件的話,應(yīng)該做什么動(dòng)作。


convert_length(Length) ->

case Length of

{centimeter, X} ->

{inch, X / 2.54};

{inch, Y} ->

{centimeter, Y * 2.54}

end.

注意, case if 都有返回值,即,在上面的例子中 case 返回 {inch,X/2.54} ? {centimeter,Y*2.54} case 的行為也可以使用守衛(wèi)來代替。


1.2.12 ? 內(nèi)建函數(shù) (BIFs)

內(nèi)建函數(shù) (BIFs) 是一個(gè)因?yàn)槟吃虮粌?nèi)嵌在 Erlang 虛擬機(jī)中的函數(shù)。 BIFs 經(jīng)常是一些 在 Erlang 上無法實(shí)現(xiàn)的功能,或在 Erlang 下實(shí)現(xiàn)起來效率不高的東西。有些 BIFs 可以 直接使用函數(shù)的名字,他們默認(rèn)是屬于 erlang 模塊下的函數(shù)。比如 trunc 函數(shù),和 ? erlang:trunc 調(diào)用是等同的。


只有很少一部分的內(nèi)建函數(shù),可以于用守衛(wèi),你也無 法在守衛(wèi)中使用你自己定義的函數(shù)。

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


1.2.13 ? 復(fù)雜函數(shù)


convert_to_c 函數(shù),和以前定義的一樣,不過我們把它做為一個(gè)帶入函數(shù)來用: ? lists:map(fun convert_to_c/1, List)


當(dāng)我們使用一個(gè)要?jiǎng)e處定義的 fun 函數(shù)的話,我們可以能過函數(shù)名 / 參數(shù)個(gè)數(shù),來區(qū)別。


sort 函數(shù)中,我們使用的 fun 函數(shù) : fun({_, {c, Temp1}}, {_, {c, Temp2}}) -> Temp1 < Temp2 end,

這里,我們介紹匿名變量” _” 。這是一個(gè)簡(jiǎn)單化的,用于一個(gè)將得到值的變量,并且我們還 需要丟棄這個(gè)值的情況下。它可以用在任何合適的場(chǎng)合中,不只在 fun 中使用。 Temp1 < Temp2 返回 true 如果 Temp1 小于 Temp2


1.3 ? 并行編程

1.3.1 ? 進(jìn)程

并發(fā),我們的意思是一種可以處理掌握若干線程同時(shí)執(zhí)行這樣的程序。

”進(jìn)程”經(jīng)常指線程間沒有共享數(shù)據(jù),”線程”指他們之間,有共享的數(shù)據(jù)或共享內(nèi)存區(qū)

Erlang 內(nèi)建函數(shù) spawn 被用于建立一個(gè)新的進(jìn)程: spawn( 模塊 , ? 導(dǎo)出的函數(shù) , ? 參數(shù)列 表 )

spawn 返回一個(gè)進(jìn)程 ID ,或 pid ,即一個(gè)進(jìn)程的唯一標(biāo)識(shí)。所以 <0.63.0> spawn 函數(shù) 的 pid ,即進(jìn)程 ID


1.3.2 ? 信息傳遞


receive 構(gòu)造用于允許進(jìn)程等待來自其它進(jìn)程的消息。它的格式是:

receive

pattern1 ->

actions1;

pattern2 ->

actions2;

....

patternN

actionsN

end.

注意,在結(jié)尾沒有” ;”

Erlang 進(jìn)程間的消息是一個(gè)有效的 Erlang 字串,即,它們可以是列表、元組、整數(shù)、 元子、 pid 等等。


每個(gè)進(jìn)程對(duì)于它收到的消息,有一個(gè)自己的輸入隊(duì)列。新的消息會(huì)放在隊(duì)列的尾部。當(dāng)一個(gè) 進(jìn)程執(zhí)行了一個(gè) receive ,隊(duì)列中第一個(gè)與匹配條件一致的消息就會(huì)從隊(duì)列中移除,并匹 配的動(dòng)作會(huì)執(zhí)行。


如果第一個(gè)匹配試沒有被匹配的話,第二個(gè)就會(huì)被檢驗(yàn),如果與隊(duì)列中移除的條件匹配了的 話,相對(duì)于第二個(gè)式子中的運(yùn)作會(huì)被執(zhí)行。第三個(gè)也依次類推。如果沒有匹配的話,那么第 一個(gè)消息就會(huì)被放回隊(duì)列中,并用第二個(gè)消息來做對(duì)應(yīng)的操作。如果第二個(gè)消息匹配的話, 相應(yīng)的動(dòng)作就會(huì)被執(zhí)行,并把第二個(gè)消息從隊(duì)列中移除 ( 并保留第一個(gè)消息和其它的消息在 隊(duì)列中 ) 。如果第二個(gè)消息也不匹配,我們會(huì)試著用第三個(gè)消息,直到達(dá)到隊(duì)列尾。如果到 達(dá)到隊(duì)列尾部,進(jìn)程就會(huì)阻塞 ( 中止執(zhí)行 ) 并等待,直到一個(gè)新的消息被收到,上面的過程 重復(fù)。


注意,” !” 是如何發(fā)送消息的,以及” !” 的句法:

Pid ! Message

即, Message( 任何東西 ) 被發(fā)到給了標(biāo)識(shí)為 Pid 的進(jìn)程。


Pong_PID ! {ping, self()},

self() 返回當(dāng)前自在運(yùn)行的進(jìn)程 ID ,在這里是” ping” 的進(jìn)程 ID


1.3.3 ? 進(jìn)程名稱注冊(cè)

有些時(shí)候進(jìn)程 可能需要知道每一個(gè)與它不相關(guān)的,啟動(dòng)的進(jìn)程的標(biāo)識(shí)。

這是由 register 這個(gè)內(nèi)建函數(shù)完成的:

register(some_atom, Pid)


1.3.4 ? 分布式編程

分布式 Erlang 的實(shí)現(xiàn),提供了一個(gè)基本 的安全機(jī)制以防止來自其它計(jì)算機(jī)的非授權(quán)的訪問 (*manual*)


Erlang 系統(tǒng)要想互相通 信,必需要相同的 magic cookie 。最簡(jiǎn)單的獲取它的方法是在你的每臺(tái)需要 Erlang 通 信的機(jī)器中的 home 文件夾中建立一個(gè) .erlang.cookie 的文件 ( Windows 系統(tǒng)中, ? home 文件夾由 $HOME 環(huán)境變量指定 - 你可能需要首先設(shè)定它。在 Linux Unix 系統(tǒng) 中,你可以忽略這一步,只需要簡(jiǎn)單的在你用戶 home 文件夾中,建立 .erlang.cookie ? 就可以了 ) .erlang.cookie 文件中需要包含相同的元子字串。如 Linux Unix 系統(tǒng)

中:

$ cd

$ cat > .erlang.cookie

this_is_very_secret

$ chmod 400 .erlang.cookie

上面的 chmod 使 .erlang.cookie 文件只可以被它的所有者訪問。這是必需的。


當(dāng)你啟動(dòng)一個(gè)需要與其它機(jī)器上的 Erlang 系統(tǒng)交互的一個(gè) Erlang 系統(tǒng)時(shí),你必須給它一 個(gè)名字,如:

erl -sname my_name

如果你希望體驗(yàn)一下分布式 Erlang ,可是你 只有一機(jī)計(jì)算機(jī)的話,你只需要啟動(dòng)兩個(gè)獨(dú)立的 Erlang 系統(tǒng)在同一臺(tái)機(jī)器上,并給他們不 同的名字就可以了。每一個(gè)運(yùn)行于計(jì)算機(jī)上的 Erlang 系統(tǒng),被稱為一個(gè) Erlang 節(jié)點(diǎn)。


( 注意: erl -sname ? 假設(shè)所有節(jié)點(diǎn)都在同一個(gè) IP 域下,如果我們想要使用其它 IP 域上

的節(jié)點(diǎn),我們使用 -name 代替,并而需要給出完全的 IP 地址


Erlang pid 已經(jīng)包 含它了有關(guān)于進(jìn)程運(yùn)行的相關(guān)信息,所以你只要知道 pid ,” !” 就可以用于發(fā)送消息,無論 目的地是在同一個(gè)節(jié)點(diǎn)上,還是其它節(jié)點(diǎn)上。


不同的是,我們?nèi)绾伟严l(fā)送到另一個(gè)節(jié)點(diǎn)上注冊(cè)的進(jìn)程中: ? {pong, Pong_Node} ! {ping, self()}, ? 我們使用元組 {regiester_name, node_name} 代替 注冊(cè)名。


一個(gè) Erlang 進(jìn)程理論上將一直運(yùn)行,直到收到不需要的信息。之所以我說“理論上”因?yàn)? ? Erlang 系統(tǒng)與活動(dòng)進(jìn)程運(yùn)享 CPU 時(shí)間。


當(dāng)沒有事可做的時(shí)候,一個(gè)進(jìn)程會(huì)終止,即,最后一個(gè)函數(shù)被調(diào)用,并返回一個(gè)值,而且不 再調(diào)用其它函數(shù)了。另一個(gè)中止進(jìn)程的方法是使用 exit/1 exit/1 的參數(shù)有特定的含意, 我們后面再說。


內(nèi)建函數(shù) whereis(RegisteredName) 檢測(cè)如果一個(gè)注冊(cè)的進(jìn)程名稱叫 ? RegisteredName 存在,如果存在,返回 pid 。否則返回 undefined


1.4 健壯性 (Robustness ? 魯棒性 )

  1. 超時(shí) (Timeouts)

    超時(shí)設(shè) 這段代碼 中:

pong() ->

receive

{ ping , ? Ping_PID } ? ->

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

Ping_PID ? ! ? pong ,

pong()

after 5000 ->

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

end.

當(dāng) 進(jìn)入 receive 代碼段 時(shí), 動(dòng) 超時(shí) 機(jī) (after 5000) ? 如果接 了消 { ping , Ping_PID } 超時(shí)將 ,如果 該消 息, 在 5000 毫秒 之后,超時(shí) 代碼段 作將 執(zhí) 行。 after 語句必須 receive 代碼段 的最后一個(gè)匹配 件。 ? receive 代碼段 中的其匹配 義優(yōu) 處理。 ? 當(dāng)然 ,我 們也 可以使用一個(gè) 一個(gè) 數(shù)的函數(shù) 超時(shí)的設(shè) 定值 after pong_timeout() ?



  1. 錯(cuò)誤處理

一個(gè)進(jìn)程如果使用 exit(normal) 退 運(yùn) 行完所有的 代碼然 退 出稱 (normal) 退 .

一個(gè)進(jìn)程如果發(fā) 生了運(yùn) 行時(shí)錯(cuò)誤 ( 例如 ? 0 ,錯(cuò)誤的匹配, 試圖調(diào) 用一個(gè)不 在的函數(shù) . 錯(cuò)誤而 結(jié)束 ? 也就 (abnormal) 退 出。

進(jìn)程 通過調(diào) link(Other_Pid) ( * manual * ) 立自 Other_Pid 進(jìn)程的 雙向 接。 ? 當(dāng) 一個(gè)進(jìn)程中 的時(shí) ,將 給每 一個(gè) 它建 立了 接的進(jìn)程發(fā) 一個(gè)信 號(hào) (signal) 個(gè)信 號(hào)包含了 發(fā) 者的 pid 和進(jìn)程 結(jié)束 的原

你可以將一個(gè) 務(wù) (transaction) 及到的所有進(jìn)程 接在一 , 如果其中的一個(gè)進(jìn)程 常退 出,所有的 該事 務(wù) 中的進(jìn)程將 全部

內(nèi) 函數(shù) spawn_link 在完成 spawn 函數(shù) 能的 時(shí)建 立了 一個(gè) 創(chuàng) 建的進(jìn)程的


可以 一個(gè)進(jìn)程接 常退 出信 號(hào) 時(shí)的缺 省退 出行 ? 時(shí)所有的信 號(hào)都 被轉(zhuǎn)換 成一個(gè)

分享到:
評(píng)論

erlang入門筆記


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 91免费精品国自产拍在线不卡 | 日韩欧美一区二区三区在线 | 韩国欧美一级毛片免费 | 亚洲va久久久久综合 | 99久热这里只有精品免费 | 久久桃花综合 | 婷婷四色| 高清影院|精品秒播3 | 新香蕉视频在线 | 亚洲精品三区 | 色综合小说天天综合网 | japanese护士奶水 | 日本一级毛片中文字幕 | 中文字幕久久网 | 99国产精品热久久久久久夜夜嗨 | 国产一级在线免费观看 | 国产福利专区精品视频 | 97视频在线免费 | 欧美亚洲另类综合 | 69精品在线观看 | 91精品自在拍精选久久 | 国产精品免费视频播放 | 久爱www成人网免费视频 | 青青青青啪视频在线观看 | 亚洲激情区| 国产精品免费一区二区三区 | 免费国产视频 | 天色噜噜噜噜 | 狠狠色香婷婷久久亚洲精品 | 一级片影院 | 国产精品a人片在线观看 | 午夜一级在线 | 久久精品国产一区二区三区 | 亚洲第一综合色 | 亚洲图片二区 | 国产精品国产三级国产无毒 | 久久精品这里只有精品 | 亚洲第成色999久久网站 | 欧美成人午夜 | 亚洲精品在线网站 | 波多野结衣久久精品 |