天天看點

Erlang程式設計

Erlang程式設計筆記

1.什麼是并發?

1.1 給并發模組化

1.1.1 開始模拟

spawn: spawn是一個Erlang基本函數,它會建立一個并發程序并傳回一個程序辨別符。

spawn的調用方式: spawn(ModName, FuncName, [Arg1, Arg2,…,ArgN])。

  • ModName:想要執行代碼的子產品名。
  • Function:子產品裡的函數名。
  • [Arg1, Arg2,…,ArgN]:一個清單,包含了想要執行的函數參數。
  • Spawn傳回的是一個程序辨別符(PID,Process IDentifier),可以用來與新建立的程序互動。

1.2 并發的好處

性能

可擴充性

容錯性

清晰性

2.Erlang速攬

2.1 Shell

2.1.1 =操作符

Erlang單詞指派: Erlang是一種函數式語言,隻能單次指派,Erlang的變量隻能綁定一次,不能重新綁定變量。

=: =不是指派操作符,其實是模式比對操作符。

2.1.2 變量和原子的文法

Erlang變量: Erlang變量都是以大寫字母開頭,以小寫字母開頭的是符号常量,它們被稱為原子(atom)。

3.基本概念

3.1 啟動和停止Erlang Shell

3.2 簡單的整數運算

Erlang整數: Erlang可以用任意長度的整數執行整數運算,在Erlang裡,整數運算時精确的,無需擔心溢出或無法用特點字長來表示某個整數。

3.3 變量

變量: 所有變量必須以大寫字母開頭,變量隻能被一次指派,Erlang中的變量都是一次性指派變量。已經被指派一個值的變量稱為綁定變量,否則稱之為未綁定變量。

=: 不是指派操作符,而是一個模式比對 操作符。=在變量未綁定之前表現類似于指派。

可變狀态: 可以修改的記憶體區域專業術語叫做可變轉态。Erlang是一種函數式程式設計語言,具有不可變狀态。

一次性指派的優勢: 在Erlang裡,變量隻不過是對某個值的引用,Erlang的實作方式用指針代表綁定變量,指向一個包含值得存儲區,這個值不能被修改。

3.4 浮點數

3.5 原子

原子: 在Erlang中,原子被用來表示常量值。原子是全局性的,不需要宏定義或包含檔案就能實作。

原子的格式: 以小寫字母開頭,後面接字母、數字、下劃線或at(@)符号。原子還可以放在單引号内(‘’),可以用這種引号形式建立以大寫字母開頭(否則會被解釋成變量)的或包含字母、數字以外字元的原子,例如‘Monday’, ‘+’, ‘*’ 或’an atom with space’。甚至可以給無需引号的原子加上引号,是以‘a’和a的意思完全一樣。Erlang中單引号和雙引号不可以互換使用(某些語言中可以互換使用),Erlang中雙引号用于給字元串字面量定界。

3.6 元組

元組: 建立元組的方法是用大括号把想要表示的值括起來,并用逗号分隔它們。元組可以嵌套。元組會在聲明它們時被主動建立,在不用它們時被銷毀。Erlang會使用垃圾收集器來回收所有未使用的記憶體,這樣不用擔心記憶體配置設定問題。

Person = {person, {name, joe}, {height, 1.82}}.
           

3.7 清單

清單: 清單被用來存放任意數量的事物,建立清單的方法是用中括号把清單元素括起來,并用逗号分隔它們。清單中的各元素可以是各種類型的。

清單頭和清單尾: 清單的第一個元素被稱為清單頭,其它的元素被稱為清單尾。

3.8 字元串

字元串: Erlang裡面沒有字元串,要在Erlang中表示字元串,可以選擇一個由整數組成的清單或者一個二進制型。當字元串表示為一個整數清單時,清單裡的每個元素都代表了一個Unicode代碼點(codepoint)。可以用字元串字面量來建立這樣一個清單,字元串字面量其實就是用雙引号圍起來的一串字元。

Name = "Hello".
           

"Hello"其實隻是一個清單的簡寫,這個清單包含了代表字元串裡各個字元的整數字元代碼。

字元串标記: Erlang中字元串使用雙引号标記。當shell列印某個清單的值時,如果清單内的所有整數都代表可列印字元,它就會将其列印成字元串字面量,否則,列印成清單記法。

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]
           

3.9 模式比對再探

4.子產品與函數

4.1 子產品是存放代碼的地方

子產品: 子產品是Erlang存放代碼的地方,子產品儲存在擴充名為.erl的檔案中,編譯後的子產品以.beam為擴充名。

-module().: 子產品申明,申明裡的子產品名必須和存放該子產品的主檔案名相同。

-export().: 導出申明。Name/N這種标記方法是指帶有N各參數的函數Name,N被稱為函數Name的元數 。未從子產品裡導出的函數隻能在子產品内部調用,已導出的函數相當于面向對象程式設計裡的公共方法,未導出的函數相當于面向對象裡的私有方法。

函數: 如下所示,函數有兩個子句,每個子句以分号隔開,最後的子句以句号加空白結束。每條子句都有一個頭部 和一個主體 ,兩者用箭頭分隔,

area({rectangle, Width, Height}) -> Wight * Height;
area({square, Side}) -> Side * Side.
           

逗号(,): 分隔函數調用、資料構造和模式中的參數。

分号(,): 分隔子句。

句号(.): 分隔函數整體,以及shell裡的表達式。

4.2 繼續購物

4.3 fun:基本的抽象單元

fun: Erlang是一種函數式程式設計語言。函數式程式設計語言還可以表示函數可以被用作其它函數的參數,也可以傳回函數。操作其它函數的函數被稱為高階函數 。Erlang中用于代表函數的資料類型被稱為fun。

以fun作為參數的函數: 标準庫裡的lists子產品導出了一些以fun作為參數的函數。

傳回fun的函數: 函數不僅可以使用fun作為參數(例如map和filter),還可以傳回fun。

例子:括号裡的東西就是傳回值。

1>Fruit = [apple, pear, orange].
[apple, pear, orange]
2>MakeTest = fun(L) -> (fun(X) -> lists:member(X, L) end) end.
3>IsFriut = MakeTest(Friut).
傳回:IsFriut = MakeTest(Fruit) = fun(Fruit) -> (fun(X) -> lists:member(X, [apple, pear, orange]) end) end.
	 IsFriut = fun(X) -> lists:member(X, [apple, pear, orange]) end.
4>IsFruit(pear).
true
5>IsFruit(apple).
true
6>IsFruit(dog).
false
           

4.4 簡單清單處理

4.5 清單推導

清單推導(list comprehension): 是無需使用fun、map或filter就能建立清單的表達式。

4.6 内置函數

内置函數: 内置函數簡稱為BIF(built-in function),是哪些作為Erlang語言一部分的函數。有些内置函數是用Erlang實作的,但大多數是用Erlang虛拟機裡的底層操作實作的。内置函數能夠提供作業系統的接口,并能執行那些無法用Erlang編寫或者用Erlang編寫比較低效的操作。比如,你無法将一個清單轉化為元組,或者查到目前的時間和日期,要執行這樣的操作,需要調用内置函數。所有的内置函數都表現的像是Erlang子產品的,但那些最常用的内置函數(如list_to_tuple)是自動導入的。

4.7 關卡

關卡(guard): 關卡是一種結構,可以用它來增加子產品比對的威力。通過使用關卡,可以對某個模式裡的變量執行簡單的測試和比較。

關卡系列: 關卡序列(guard sequence)是指單一或一系列的關卡,用分号(;)分隔。對于關卡序列G1;G2; …; Gn,隻要其中有一個關卡(G1、G2……)的值為true,它的值就為true。關卡由一系列關卡表達式組成,用逗号(,)分隔。關卡GuardExpr1, GuardExpr2, … ,

GuardExprN隻有在所有的關卡表達式(GuardExpr1、GuardExpr2……)都為true時才為true。

4.8 case和if表達式

case文法:

case Expression of
	Pattern1 [when Guard1] -> Expr_seq1;
	Pattern2 [when Guard2] -> Expr_seq2;
	...
end
           

case執行過程如下:首先計算表達式Expression的值,假設它的值為value,接下來value值輪流與Pattern1、Pattern2進行模式比對,直到比對成功。一旦比對成功,相應的表達式就會執行;如果所有表達式都不比對,就會發生異常錯誤。

4.9 建構自然順序的清單

5.記錄與映射組

記錄: 記錄其實是元組的另一種形式,通過使用記錄,可以給元組裡的各個元素關聯一個名稱。

映射組: 映射組是鍵值對的關聯集合。鍵可以是Erlang的任何資料類型。

5.1 何時使用映射組或記錄

5.2 通過記錄命名元組裡的項

記錄: 記錄的文法格式

record{Name, {
              %%以下兩個鍵帶有預設值
              key1 = Default1,
              key2 = Default2,
              ...
			  %%下一行就相當于key3 = undefined
			  key3, 
             }
      }