Erlang速覽

Windows環(huán)境下安裝Erlang

??在http://www.erlang.org/downloads下載安裝了Erlang之后处硬,再配置path系統(tǒng)變量Erlang安裝目錄/bin手报。之后在cmd命令行中,輸入erl命令,即可進(jìn)入Erlang shell環(huán)境频轿。

基本概念

注釋

??Erlang里的注釋從一個(gè)百分號(hào)字符(%)開(kāi)始饥侵,一直延伸到行尾。Erlang沒(méi)有塊注釋哩簿。
??根據(jù)規(guī)范宵蕉,與代碼同處一行的注釋以一個(gè)%開(kāi)頭酝静,獨(dú)占一行的注釋以兩個(gè)%%開(kāi)頭。

整數(shù)和浮點(diǎn)數(shù)

??整數(shù)無(wú)大小限制羡玛,$符號(hào)加字符可以得到字符的編碼數(shù)值别智,比如$a,可以得到a的編碼數(shù)值稼稿。
??在Erlang里浮點(diǎn)數(shù)都是雙精度浮點(diǎn)數(shù)薄榛。

運(yùn)算符

??有兩種除法運(yùn)算,使用/運(yùn)算符返回浮點(diǎn)數(shù)让歼,div運(yùn)算符返回整數(shù)敞恋,rem運(yùn)算符是求余,也可以使用math模塊的運(yùn)算函數(shù)谋右。
??任何類型之間都可以使用比較運(yùn)算符進(jìn)行比較硬猫,數(shù)值小于原子,元組小于列表倚评,而原子既小于元組也小于列表浦徊。
??小于或等于運(yùn)算符寫(xiě)作=<,大于或等于運(yùn)算符寫(xiě)作>=天梧。
??=:=是完全相等運(yùn)算符(值和類型都相同)盔性,=/=是不完全相等運(yùn)算符。如果想執(zhí)行不考慮類型的比較呢岗,比如比較2和2.0冕香,則需要使用==運(yùn)算符,其否定形式是/=后豫。

位串

??<< >>內(nèi)用逗號(hào)分隔整數(shù)序列悉尾,整數(shù)取值范圍是0~255,也可以使用字符串代替整數(shù)挫酿。

變量和符號(hào)常量

??Erlang是一種函數(shù)式語(yǔ)言构眯,所以一旦定義了X = 123,那么X永遠(yuǎn)就是123早龟,不允許改變惫霸。如果再執(zhí)行X = abc,則會(huì)拋錯(cuò)葱弟,當(dāng)可以重復(fù)執(zhí)行X = 123壹店。等號(hào)只是模式匹配,而不是賦值操作芝加,通過(guò)以下觀察最后例子123=X12=X硅卢,可以明白一些,這種機(jī)制有點(diǎn)類似于==操作,可以用來(lái)做測(cè)試使用将塑。

1> X=123.
123
2> X=abc.
** exception error: no match of right hand side value abc
3> X=123.
123
4> Y=123.
123
5> X=Y.
123
6> K=abc.
abc
7> X=K.
** exception error: no match of right hand side value abc
8> 123=X.
123
9> 12=X.
** exception error: no match of right hand side value 123

??沒(méi)有可變變量將如何編程脉顿?在Erlang里怎樣表達(dá)X = X + 1這類概念?Erlang的方式是創(chuàng)建一個(gè)名字未被使用過(guò)的新變量(比方說(shuō)X1)抬旺,然后編寫(xiě)X1 = X + 1弊予。
??請(qǐng)注意Erlang的變量以大寫(xiě)字母開(kāi)頭。所以X开财、This和A_long_name都是變量汉柒。以小寫(xiě)字母開(kāi)頭的名稱(比如monday或friday)不是變量,而是符號(hào)常量责鳍,它們被稱為原子(atom)碾褂。

原子

??在Erlang里,原子被用于表示常量值历葛。原子以小寫(xiě)字母開(kāi)頭正塌,后接一串字母、數(shù)字恤溶、下劃線(_)或at(@)符號(hào)乓诽。
??原子還可以放在單引號(hào)(')內(nèi)≈涑蹋可以用這種引號(hào)形式創(chuàng)建以大寫(xiě)字母開(kāi)頭(否則會(huì)被解釋成變量)或包含字母數(shù)字以外字符的原子鸠天,例如'Monday'、'Tuesday'帐姻、'+'稠集、'*'和'an atom with spaces'。
??true和false這兩個(gè)原子可以用于布爾運(yùn)算饥瓷。undefined表示未知量的占用符剥纷。

元組

??元組把一些數(shù)量固定的項(xiàng)目歸組成單一的實(shí)體,元祖這樣定義:P = {joe, 1.82}呢铆。
??在Erlang中晦鞋,=不是賦值語(yǔ)句,而是模式匹配操作符棺克。如果想要提取P = {joe, 1.82}里面的1.82這個(gè)值鳖宾,需要執(zhí)行{joe,X}=P,這樣1.82這個(gè)值就會(huì)賦給變量X逆航。

列表

??列表(list)被用來(lái)存放任意數(shù)量的事物。創(chuàng)建列表的方法是用中括號(hào)把列表元素括起來(lái)渔肩,并用逗號(hào)分隔它們因俐。
??列表的第一個(gè)元素被稱為列表頭(head),假設(shè)把列表頭去掉,剩下的就被稱為列表尾(tail)抹剩。訪問(wèn)列表頭是一種非常高效的操作撑帖。
??可以給列表T的開(kāi)頭添加不止一個(gè)元素,寫(xiě)法是[E1,E2,..,En|T]澳眷。
??和其他情況一樣胡嘿,我們可以用模式匹配操作來(lái)提取某個(gè)列表里的元素。如果有一個(gè)非空列表L钳踊,那么表達(dá)式[X|Y] = L(X和Y都是未綁定變量)會(huì)提取列表頭作為X衷敌,列表尾作為Y。

字符串

??嚴(yán)格來(lái)說(shuō)拓瞪,Erlang里沒(méi)有字符串缴罗。Name="Hello"Hello其實(shí)只是一個(gè)列表的簡(jiǎn)寫(xiě)祭埂,這個(gè)列表包含了代表字符串里各個(gè)字符的整數(shù)字符代碼面氓。
??當(dāng)shell打印某個(gè)列表的值時(shí),如果列表內(nèi)的所有整數(shù)都代表可打印字符蛆橡,它就會(huì)將其打印成字符串字面量舌界。否則,打印成列表記法泰演。不需要知道代表某個(gè)字符的是哪一個(gè)整數(shù)呻拌,可以把“美元符號(hào)語(yǔ)法”用于這個(gè)目的

1> [1,2,3].
[1,2,3]
2> [83,117,114,112,114,105,115,101].
"Surprise"
3> [$S,$u,$r,$p,$r,$i,$s,$e].
"Surprise"
模式匹配
     模式 = 單元                                  結(jié) 果
{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]

模塊和函數(shù)

模塊

??模塊是Erlang的基本代碼單元耕突。模塊保存在擴(kuò)展名為.erl的文件里笤成,而且必須先編譯才能運(yùn)行模塊里的代碼。編譯后的模塊以.beam作為擴(kuò)展名眷茁。
??創(chuàng)建模塊文件炕泳,文件名是name.erl。

-module(name)
-export([FuncName1/N1,FuncName2/N2,...])

??-module(name)表明此文件是哪個(gè)模塊上祈,name是文件名(除掉erl后綴)培遵。-export([FuncName1/N1,FuncName2/N2,...])指明了模塊里哪些函數(shù)可以從模塊外部進(jìn)行調(diào)用浙芙,斜杠后面的N是數(shù)字,表示函數(shù)有多少個(gè)參數(shù)籽腕。未從模塊里導(dǎo)出的函數(shù)只能在模塊內(nèi)調(diào)用嗡呼。

函數(shù)

??Erlang是一種函數(shù)式編程語(yǔ)言。函數(shù)式編程語(yǔ)言表示函數(shù)可以被用作其他函數(shù)的參數(shù)皇耗,也可以返回函數(shù)南窗。操作其他函數(shù)的函數(shù)被稱為高階函數(shù)(higher-order function),而在Erlang中用于代表函數(shù)的數(shù)據(jù)類型被稱為fun郎楼。

-module(my_module).
-export([pie/0]).

pie() -> 
      3.14.

??以-開(kāi)頭的語(yǔ)句屬于聲明万伤,-module聲明指定了模塊的名字,必須和文件名一致箭启。-export聲明指定了模塊內(nèi)哪些函數(shù)是外部可以調(diào)用的壕翩,pie/0后面的0的函數(shù)參數(shù)數(shù)量。

??pie() -> 3.14.是函數(shù)定義傅寡,函數(shù)首部(函數(shù)名和參數(shù)列表)和函數(shù)體使用->分隔放妈,函數(shù)的返回值不需要return關(guān)鍵字,返回值就是函數(shù)體中表達(dá)式的值荐操,但要注意函數(shù)定義的末尾必須加上句號(hào).芜抒。

-module(geometry).
-export([area/1]).

area({rectangle,Width,Height}) -> Width*Height;#第一個(gè)子句
area({squre,Side})                    -> Side*Side.#第二個(gè)字句

??area函數(shù)有兩個(gè)子句。這些子句由一個(gè)分號(hào)隔開(kāi)托启,最后的子句以句號(hào)加空白結(jié)束宅倒。每條子句都有一個(gè)頭部和一個(gè)主體,兩者用箭頭(->)分隔屯耸。頭部包含一個(gè)函數(shù)名拐迁,后接零個(gè)或更多個(gè)模式,主體則包含一列表達(dá)式疗绣,它們會(huì)在頭部里的模式與調(diào)用參數(shù)成功匹配時(shí)執(zhí)行线召。這些子句會(huì)根據(jù)它們?cè)诤瘮?shù)定義里出現(xiàn)的順序進(jìn)行匹配。

1> c(geometry).
{ok,geometry}
2> geormetry:area({rectangle,10,5}).
50
3> geormetry:area({square,3}).
9
內(nèi)置函數(shù)和標(biāo)準(zhǔn)庫(kù)

??erlang模塊包含了整個(gè)Erlang系統(tǒng)最核心的函數(shù)多矮,io模塊處理文本輸入輸出缓淹,dict模塊提供了基于散列的關(guān)聯(lián)數(shù)組(字典),array模塊提供了可擴(kuò)展的塔逃、帶整數(shù)索引的數(shù)組讯壶。erlang模塊中的有些函數(shù)會(huì)被自動(dòng)導(dǎo)入,比如self()函數(shù)其實(shí)erlang:self()湾盗,因?yàn)樗呀?jīng)被自動(dòng)導(dǎo)入伏蚊,所以可以省略erlang:

標(biāo)點(diǎn)符號(hào)使用
  • 逗號(hào)(,)分隔函數(shù)調(diào)用格粪、數(shù)據(jù)構(gòu)造和模式中的參數(shù)
  • 分號(hào)(;)分隔子句丙挽。我們能在很多地方看到子句肺孵,例如函數(shù)定義,以及case颜阐、if、try..catch和receive表達(dá)式
  • 句號(hào)(.)(后接空白)分隔函數(shù)整體吓肋,以及shell里的表達(dá)式

??有一種簡(jiǎn)單的方法可以記住這些:想想英語(yǔ)凳怨。句號(hào)分隔句子,分號(hào)分隔子句是鬼,逗號(hào)則分隔下級(jí)子句肤舞。逗號(hào)象征短程,分號(hào)象征中程均蜜,句號(hào)則象征長(zhǎng)程李剖。

編譯

??在erl文件目錄下進(jìn)入shell,執(zhí)行c(模塊名)即可對(duì)模塊名.erl進(jìn)行編譯囤耳,編譯完成后會(huì)產(chǎn)生.beam文件篙顺,之后在shell里就可以通過(guò)模塊名:方法名()調(diào)用模塊里的函數(shù)。
??在Erlang里有一些用在Shell的函數(shù)充择,格式是name(args)德玫。

case表達(dá)式
case Expression of 
  Pattern1 [when Guard1] -> Expr_seq1;
  Pattern2 [when Guard2] -> Expr_seq2;
  ...
end

??case的執(zhí)行過(guò)程如下:首先,Expression被執(zhí)行椎麦,假設(shè)它的值為Value宰僧。隨后,Value輪流與Pattern1(帶有可選的關(guān)卡Guard1)观挎、Pattern2等模式進(jìn)行匹配琴儿,直到匹配成功。一旦發(fā)現(xiàn)匹配嘁捷,相應(yīng)的表達(dá)式序列就會(huì)執(zhí)行造成,而表達(dá)式序列執(zhí)行的結(jié)果就是case表達(dá)式的值。如果所有模式都不匹配普气,就會(huì)發(fā)生異常錯(cuò)誤(exception)谜疤。

if表達(dá)式
if
  Guard1 -> 
    Expr_seq1;
  Guard2 ->
    Expr_seq2;
  ...
end

??它的執(zhí)行過(guò)程如下:首先執(zhí)行Guard1。如果得到的值為true现诀,那么if的值就是執(zhí)行表達(dá)式序列Expr_seq1所得到的值夷磕。如果Guard1不成功,就會(huì)執(zhí)行Guard2仔沿,以此類推坐桩,直到某個(gè)關(guān)卡成功為止。if表達(dá)式必須至少有一個(gè)關(guān)卡的執(zhí)行結(jié)果為true封锉,否則就會(huì)發(fā)生異常錯(cuò)誤绵跷。

記錄與映射組

記錄

??對(duì)于小型元組而言膘螟,記住各個(gè)元素代表什么幾乎不成問(wèn)題,但當(dāng)元組包含大量元素時(shí)碾局,給各個(gè)元素命名就更方便了荆残。一旦命名了這些元素,就可以通過(guò)名稱來(lái)指向它們净当,而不必記住它們?cè)谠M里的具體位置内斯。記錄其實(shí)就是元組。

-record(Name,{
        %%以下兩個(gè)鍵帶有默認(rèn)值
        key1=Default1,
        key2=Default2,
        ...
        %%下一行就相當(dāng)于key3=undefined
        key3,
        ...
}

??在之前的例子里像啼,Name是記錄名俘闯。key1、key2這些是記錄所含各個(gè)字段的名稱忽冻,它們必須是原子真朗。記錄里的每個(gè)字段都可以帶一個(gè)默認(rèn)值,如果創(chuàng)建記錄時(shí)沒(méi)有指定某個(gè)字段的值僧诚,就會(huì)使用默認(rèn)值遮婶。
??記錄的定義既可以保存在Erlang源代碼文件里,也可以由擴(kuò)展名為.hrl的文件保存振诬,然后包含在Erlang源代碼文件里蹭睡。

-record{todo,{status=reminder,who=joe,text}}.
%% 創(chuàng)建記錄
1> X1 = #todo{status=urgent,text="Fix errate in book"}.
2> X2 = X1#todo{status=done}.
%% 提取記錄
3> #todo{who=W,text=Txt}=X2.
4> W.
5> Txt.
6> X2%todo.text.
映射組:關(guān)聯(lián)式鍵-值存儲(chǔ)
#{ Key1 Op Val1,Key2 Op Val2,...KeyN Op ValN }
NewMap = OldMap#{ Key1 Op Val1,...KeyN Op ValN }

??Op是=>或:=這兩個(gè)符號(hào)的其中一個(gè)。
??表達(dá)式K => V有兩種用途赶么,一種是將現(xiàn)有鍵K的值更新為新值V肩豁,另一種是給映射組添加一個(gè)全新的K-V對(duì)。這個(gè)操作總是成功的辫呻。
??表達(dá)式K := V的作用是將現(xiàn)有鍵K的值更新為新值V清钥。如果被更新的映射組不包含鍵K,這個(gè)操作就會(huì)失敗放闺。
??鍵和值可以是任何有效的Erlang數(shù)據(jù)類型祟昭。

異常處理

??Erlang有兩種方法來(lái)捕捉異常錯(cuò)誤。第一種是把拋出異常錯(cuò)誤的調(diào)用函數(shù)封裝在一個(gè)try...catch表達(dá)式里怖侦,另一種是把調(diào)用封裝在一個(gè)catch表達(dá)式里篡悟。

try FucOrExpressionSeq of
  Pattern1 [when Guard1] -> Expression1;
  Pattern2 [when Guard2] -> Expression2;
  ...
catch
  ExceptionType1: ExPattern1 [when Guard1] -> ExExpression1;
  ExceptionType2: ExPattern2 [when Guard2] -> ExExpression2;
  ...
after
  AfterExpressions
end

??try...catch就像是case表達(dá)式的強(qiáng)化版。它基本上就是case表達(dá)式加上最后的catch和after區(qū)塊匾寝。
??try...catch的工作方式如下:首先執(zhí)行FuncOrExpessionSeq搬葬。如果執(zhí)行過(guò)程沒(méi)有拋出異常錯(cuò)誤,那么函數(shù)的返回值就會(huì)與Pattern1(以及可選的關(guān)卡Guard1)艳悔、Pattern2等模式進(jìn)行匹配急凰,直到匹配成功。如果能匹配猜年,那么整個(gè)try...catch的值就通過(guò)執(zhí)行匹配模式之后的表達(dá)式序列得出抡锈。
??如果FuncOrExpressionSeq在執(zhí)行中拋出了異常錯(cuò)誤疾忍,那么ExPattern1等捕捉模式就會(huì)與它進(jìn)行匹配,找出應(yīng)該執(zhí)行哪一段表達(dá)式序列床三。ExceptionType是一個(gè)原子(throw一罩、exit和error其中之一),它告訴我們異常錯(cuò)誤是如何生成的撇簿。如果省略了ExceptionType擒抛,就會(huì)使用默認(rèn)值throw。

指令

宏定義
-define(PI,3.14).
circumference(Radius) -> Redius * 2 * ?PI.

??引用宏定義必須以問(wèn)號(hào)补疑?開(kāi)頭,在正式編譯之前歹撒,這段代碼會(huì)被展開(kāi)成

circumference(Radius) -> Redius * 2 * 3.14).

??常見(jiàn)的預(yù)定義宏:MODULE宏莲组,它展開(kāi)后當(dāng)前正在編譯的模塊的名稱,還有FILELINE宏表示當(dāng)前處于哪個(gè)源文件的哪一行暖夭。

文件包含

-include("filename.hrl").

??預(yù)處理器會(huì)讀取被包含文件的內(nèi)容并將之插入到include指令所處的位置锹杈,這類文件一般只有聲明,沒(méi)有函數(shù)迈着,一般出現(xiàn)在模塊源文件的頭部竭望,所以也叫頭文件,按照慣例裕菠,Erlang頭文件以.hrl為擴(kuò)展名咬清。
??-include.指令會(huì)在當(dāng)前目錄以及列于包含路徑內(nèi)的目錄查找名為finename.hrl的文件。如果要包含其他Erlang應(yīng)用或庫(kù)的頭文件奴潘,需要使用-includelib(應(yīng)用名/include/file.erl).指令旧烧,因?yàn)閼?yīng)用名一般帶有版本號(hào)(比如應(yīng)用名-0.0.1),使用-includelib指令可以省略應(yīng)用名后的版本號(hào)画髓,防止因?yàn)槠渌麘?yīng)用升級(jí)造成找不到文件掘剪。
??-includelib會(huì)相對(duì)于Erlang系統(tǒng)現(xiàn)有應(yīng)用(尤其是所有隨Erlang一并發(fā)布的標(biāo)準(zhǔn)庫(kù))的安裝路徑來(lái)查找文件。

條件編譯
-ifdef(MacroName).
xxx %如果定義了名字為MacroName的宏奈虾,就編譯這里的代碼
-ifndef(MacroName). %如果沒(méi)定義了名字為MacroName的宏夺谁,就編譯這里的代碼
-else.
-endif.

并發(fā)

??Erlang的并發(fā)是基于進(jìn)程(process)的。進(jìn)程是一些獨(dú)立的小型虛擬機(jī)肉微,可以執(zhí)行Erlang函數(shù)匾鸥。
??三個(gè)新的基本函數(shù):spawnsendreceive浪册。spawn創(chuàng)建一個(gè)并行進(jìn)程扫腺,send向某個(gè)進(jìn)程發(fā)送消息,receive則是接收消息村象。
??Erlang進(jìn)程意外退出時(shí)笆环,會(huì)產(chǎn)生一個(gè)退出信號(hào)攒至,所有與瀕死進(jìn)程鏈接 的進(jìn)程都會(huì)收到這個(gè)信號(hào)。默認(rèn)情況下躁劣,接收方會(huì)一并退出并將信號(hào)傳播給與它鏈接的其他進(jìn)程迫吐,直到所有直接或間接鏈接在一起的進(jìn)程系統(tǒng)退出為止。
??可以改寫(xiě)退出信號(hào)默認(rèn)的傳播行為账忘,通過(guò)設(shè)置trap_exit進(jìn)程標(biāo)記志膀,可以令進(jìn)程不再服從外來(lái)的退出信號(hào),而是將其捕捉鳖擒,這種情況下溉浙,進(jìn)程收到信號(hào)后,會(huì)先將其轉(zhuǎn)為一條格式為{'EXIT',pid,Reason}的消息蒋荚,該消息描述了哪個(gè)進(jìn)程處于什么原因而發(fā)生故障戳稽。這類會(huì)捕捉信號(hào)的進(jìn)程成為系統(tǒng)進(jìn)程,可用于匯報(bào)故障,以及重啟故障的子系統(tǒng),這類進(jìn)程也稱為監(jiān)督者销凑。

OTP

??使用OTP時(shí)彤叉,需要實(shí)現(xiàn)行為模式(類似于java里面的即接口),每種行為模式都有自己需要實(shí)現(xiàn)的函數(shù)和調(diào)用規(guī)范,比如gen_server行為模式,實(shí)現(xiàn)模塊里面需要實(shí)現(xiàn)init/1、handle_call/3乓序、handle_cast/2、handle_info/2舟奠、terminate/2竭缝、code_change/3回調(diào)函數(shù)。

%% 最精簡(jiǎn)的gen_server行為模式實(shí)現(xiàn)模塊
-module(...).
-behaviour(gen_server).% 行為模式實(shí)現(xiàn)的名稱
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
        terminate/2, code_change/3]).
-record(state,{}).
init([]) ->
    {ok,#state{}}

handle_call(_Request,_Form,State) ->
    Reply=ok,
    {reply,Reply,State}.

handle_cast(_Msg,State) ->
    {noreply,State}.

handle_info(_Info,State) ->
    {noreply,State}.

terminate(_Reason,State) ->
    ok.

code_change(_OldVsn,State,_Extra) ->
    {ok,State}.

??實(shí)現(xiàn)了行為模式后沼瘫,還需要一個(gè)容器(功能類似于J2EE里面的容器抬纸,比如Tomcat)。容器是一個(gè)進(jìn)程耿戚,它執(zhí)行的是某個(gè)庫(kù)模塊中的代碼湿故,并且會(huì)調(diào)用與行為模式實(shí)現(xiàn)相對(duì)應(yīng)的回調(diào)模塊來(lái)處理應(yīng)用相關(guān)的邏輯,該庫(kù)模塊的名稱與對(duì)應(yīng)的行為模式的名稱一致膜蛔。
??庫(kù)模塊包含了行為模式中的通用代碼坛猪,其中包括新容器的啟動(dòng)函數(shù),比如對(duì)于gen_server行為模式而言皂股,這部分代碼就位于Erlang/OTP庫(kù)中stdlib部分的gen_server模塊中墅茉。當(dāng)你調(diào)用gen_server:start(... , foo , ...)時(shí),就會(huì)創(chuàng)建一個(gè)新的以foo為回調(diào)模塊的gen_server容器。我們將新容器進(jìn)程的啟動(dòng)稱作行為模式的實(shí)例化就斤。

行為模式實(shí)現(xiàn)模塊的典型布局

首部
??以%%%開(kāi)頭表示是文件注釋悍募,@開(kāi)頭是EDoc標(biāo)注,EDoc可以直接通過(guò)源碼標(biāo)注生成文檔(與JavaDoc類似)洋机,是隨標(biāo)準(zhǔn)Erlang/OTP發(fā)行版一同發(fā)布的文檔生成工具坠宴。

%%%-------------------------------------------------------------------
%%% @author Martin & Eric <erlware-dev@googlegroups.com>
%%%  [http://www.erlware.org]
%%% @copyright 2008-2010 Erlware
%%% @doc RPC over TCP server. This module defines a server process that
%%%      listens for incoming TCP connections and allows the user to
%%%      execute RPC commands via that TCP stream.
%%% @end
%%%-------------------------------------------------------------------


??-module(...).指令,與文件名對(duì)應(yīng)
??-behaviour(...)指令绷旗,它告知編譯器這個(gè)模塊是哪個(gè)行為模式的一個(gè)實(shí)現(xiàn)喜鼓,之后必須實(shí)現(xiàn)該行為模式的所有函數(shù),否則編譯時(shí)會(huì)報(bào)錯(cuò)衔肢。
??export()指令庄岖,通常要寫(xiě)兩個(gè),一個(gè)是自己的API角骤,一個(gè)是行為模式接口要求導(dǎo)出的函數(shù)顿锰。
??接著就是一些聲明和預(yù)處理定義。
API
??API一般只是對(duì)庫(kù)模塊函數(shù)進(jìn)行一個(gè)封裝启搂。使用API可以隱藏底層使用的行為模式,使用者不需要調(diào)用庫(kù)模塊函數(shù)來(lái)啟動(dòng)容器刘陶,只需要調(diào)用API即可胳赌。

%% 調(diào)用start_link(Port)時(shí),會(huì)啟動(dòng)一個(gè)容器匙隔,進(jìn)而再調(diào)用init方法
start_link(Port) ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []).

init([Port]) ->
    {ok, LSock} = gen_tcp:listen(Port, [{active, true}]),
    {ok, #state{port = Port, lsock = LSock}, 0}.

行為模式接口
??行為模式所需的回調(diào)函數(shù)疑苫。
內(nèi)部函數(shù)
??API和行為模式接口所需的輔助函數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末纷责,一起剝皮案震驚了整個(gè)濱河市捍掺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌再膳,老刑警劉巖挺勿,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異喂柒,居然都是意外死亡不瓶,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)灾杰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蚊丐,“玉大人,你說(shuō)我怎么就攤上這事艳吠÷蟊福” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)凛篙。 經(jīng)常有香客問(wèn)我黍匾,道長(zhǎng),這世上最難降的妖魔是什么鞋诗? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任膀捷,我火速辦了婚禮,結(jié)果婚禮上削彬,老公的妹妹穿的比我還像新娘全庸。我一直安慰自己,他們只是感情好融痛,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布壶笼。 她就那樣靜靜地躺著,像睡著了一般雁刷。 火紅的嫁衣襯著肌膚如雪覆劈。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,837評(píng)論 1 290
  • 那天沛励,我揣著相機(jī)與錄音责语,去河邊找鬼。 笑死目派,一個(gè)胖子當(dāng)著我的面吹牛坤候,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播企蹭,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼白筹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了谅摄?” 一聲冷哼從身側(cè)響起徒河,我...
    開(kāi)封第一講書(shū)人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎送漠,沒(méi)想到半個(gè)月后顽照,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闽寡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年棒厘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片下隧。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奢人,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出淆院,到底是詐尸還是另有隱情何乎,我是刑警寧澤句惯,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站支救,受9級(jí)特大地震影響抢野,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜各墨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一指孤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贬堵,春花似錦恃轩、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蒸殿,卻和暖如春筷厘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宏所。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工酥艳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爬骤。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓玖雁,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親盖腕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349