Erlang讀音/ˈɜːrlæŋ/
。第一次見到的時候總感受怎麼讀都讀不對,後來在維基上看到Erlang標註了音標,才能準確的讀出來,並且也沒那麼怪異。由於工做纔有機會接觸這門語言,也所以只有三天的時間能夠看《Erlang程序設計》這本書。學習這門語言的時候帶着一個工做目標:把一個Erlang日誌收集分析統計的代碼轉換成Python的。而Erlang的風格是儘可能不寫註釋,儘可能在寫函數名和變量名的時候表達清楚代碼的含義。這樣一來學習Erlang就成了必要的,很慶幸,領導給了三天時間學習,三天時間基本也足夠了。除了這一片基礎語法的入門篇以外,後續還有一篇或者兩篇併發編程和分佈式編程的,畢竟這個纔是Erlang擅長的領域。話很少說,show me your article
html
<!--more-->python
依賴工具:程序員
下載連接:shell
IDEA配置Erlang插件:編程
全部的變量都必須以大寫字母開頭,變量只可一次賦值,賦值以後不可在變。 f()函數釋放shell綁定變量。segmentfault
case
、if
、try..catch
、receive
表達式中的模式匹配時,用分號「;」分界恆等測試符號 =:=以及不等測試符號 =/=數據結構
當程序中某處的語法要求只能使用單個表達式可是邏輯上又須要在此使用多個表達式時,就可使用begin...end快表達式併發
begin Expr1, ... ExprN end
1> Point = {point, 20, 43}. {point,20,43} 2> {point, x, y} = Point. ** exception error: no match of right hand side value {point,20,43} 3> {point, X, Y} = Point. {point,20,43} 4> X. 20 5> Y. 43 6> Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}. {person,{name,{first,joe},{last,armstrong}},{footsize,42}} 7> {_, {_, {_, Who}, {_, _}}, {_, Size}} = Person. {person,{name,{first,joe},{last,armstrong}},{footsize,42}} 8> Who. joe 9> Size. 42
豎線符號|app
列表操做演示代碼分佈式
1> L = [1+7, hello, 2-2, {cost, apple, 30-20}, 3]. [8,hello,0,{cost,apple,10},3] 2> L1 = [123, {oranges, 4} | L]. [123,{oranges,4},8,hello,0,{cost,apple,10},3] 3> [E1 | L2] = L1. [123,{oranges,4},8,hello,0,{cost,apple,10},3] 4> E1. 123 5> L2. [{oranges,4},8,hello,0,{cost,apple,10},3] 6> [E2, E3 | L3] = L2. [{oranges,4},8,hello,0,{cost,apple,10},3] 7> E3. 8
列表表達式
形式:[F(X) || X <- L]
1> L = [1, 2, 3, 4, 5]. [1,2,3,4,5] 2> [2 * X || X <- L]. [2,4,6,8,10] 3> [X || {a, X} <- [{a, 1}, {b, 2}, {c, 3}, {a, 4}, hello, "wow"]]. [1,4]
Erlang的字符串是一個整數列表。整數列表的內容由每個字符對應的ascii碼構成
1> I = $s. 115 2> [I-32, $u, $r, $p, $r, $i, $s, $e]. "Surprise" 3> $r. 114 4> [I-32, $u, $r, $p, 114, $i, $s, $e]. "Surprise"
映射組是一個由多個Key-Vaule結構組成的符合數據類型,相似於Python的字典。具體使用以下
1> M1 = #{"name" => "alicdn", "percentage" => 80}. #{"name" => "alicdn","percentage" => 80} 2> maps:get("name", M1). "alicdn" 3> M2 = maps:update("percentage", 50, M1). #{"name" => "alicdn","percentage" => 50} 4> map_size(M1). 2 5> #{"name" := X, "percentage" := Y} = M2. #{"name" => "alicdn","percentage" => 50} 6> X. "alicdn" 7> Y. 50
構造映射組和模式匹配時的符號不同,=>
和:=
的區別。常見的put方法參見erlang maps庫的使用。
-import(lists, [map/2, sum/1]).
導出模塊中的函數:
-export([start/0, area/2]).
-compile(export_all).
,避免在開發階段常常會向export中添加函數或者刪除函數-module(learn_test). -author("ChenLiang"). %% API -export([area/1]). area({rectangle, Width, Height}) -> Width * Height; area({circle, R}) -> 3.14159 * R * R; area({square, X}) -> X * X.
編譯模塊,調用函數
1> c(learn_test). {ok,learn_test} 2> learn_test:area({circle, 2.0}). 12.56636 3>
同名同目(參數數量,arity)的纔是同一個函數。所以函數名相同,目不相同的函數是徹底不一樣的兩個函數。同名不一樣目的函數一般做爲輔助函數。
示例代碼:計算列表元素的和
-module(learn_test). -author("ChenLiang"). %% API -export([sum/1]). sum(L) -> sum(L, 0). sum([], N) -> N; sum([H|T], N) -> sum(T, H + N).
erlang中的匿名函數就是fun。fun也能夠有若干個不一樣的字句。
1> Z = fun(X) -> 2*X end. #Fun<erl_eval.6.50752066> 2> Double = Z. #Fun<erl_eval.6.50752066> 3> Double(4). 8 4> TempConvert = fun({c, C}) -> {f, 32 + C * 9 / 5}; 5> ({f, F}) -> {c, (F - 32) * 5 / 9} 6> end. #Fun<erl_eval.6.50752066> 7> TempConvert({c, 100}). {f,212.0} 8> TempConvert({f, 212}). {c,100.0}
返回fun或者接受fun做爲參數的函數都稱爲高階函數。
以fun爲參數的函數
常見的是lists模塊中的map(Fun, List1) -> List2,filter(Pred, List1) -> List2函數。
lists模塊的具體使用參見:https://www.erlang.org/doc/ma...
1> Even = fun(X) -> X rem 2 =:= 0 end. #Fun<erl_eval.6.50752066> 2> lists:map(Even, [1, 2, 3, 4, 5, 6]). [false,true,false,true,false,true] 3> lists:filter(Even, [1, 2, 3, 4, 5, 6]). [2,4,6]
返回fun的函數
通常在返回的函數內部封裝了一些變量和邏輯。一般狀況下不寫返回fun的函數。
1> Mult = fun(Times) -> (fun(X) -> X * Times end ) end. #Fun<erl_eval.6.50752066> 2> Triple = Mult(3). #Fun<erl_eval.6.50752066> 3> Triple(4). 12
強化模式匹配的功能,給模式匹配增長一些變量測試和比較的能力
max(X, Y) when X > Y -> X; max(_, Y) -> Y.
記錄是Erlang中基於元組的key-value數據定義,使用示例以下:
-module(learn_test). -author("ChenLiang"). %% API -export([record_test1/0, record_test2/0]). -record(person, {name, age=18, hobby=["erlang"]}). %% record定義能夠存放於hrl和erl中 record_test1() -> Person = #person{name="hahaha"}, %% 爲record中字段賦值 Person#person.hobby. %% 經過.操做符訪問record中字段 record_test2() -> Person = #person{}, #person{name = Name} = Person, %% 經過模式匹配獲取record字段 Name. %% 輸出undefined
某些文件的擴展名爲 .hrl
。這些.hrl
是在 .erl
文件中會用到的頭文件,使用方法以下:
-include("File_Name").
例如:
-include("mess_interface.hrl").
.hrl 文件中能夠包含任何合法的 Erlang 代碼,可是一般裏面只包含一些記錄和宏的定義。
case語句語法
case Experssion of Pattern1 [when Guard1] -> Expr_seq1; Pattern2 [when Guard2] -> Expr_seq2; ... end
將Expression的結果和各個Pattern逐個匹配,匹配成功,則計算表達式序列的值,並返回。所有匹配不到,則直接報錯。
case語句使用示例:
-module(learn_test). -author("ChenLiang"). %% API -export([filter/2]). filter(P, [H|T]) -> case P(H) of true -> [H|filter(P, T)]; false -> filter(P, T) end ; filter(_, []) -> [].
在erl shell中運行結果以下:
1> c(learn_test). {ok,learn_test} 2> learn_test:filter(fun(X) -> X rem 2 =:= 0 end, [1, 2, 3, 4, 5]). [2,4]
if語句使用示例
-module(learn_test). -author("ChenLiang"). %% API -export([bigger/2]). bigger(X, Y) -> if X > Y -> X; X < Y -> Y; true -> -1 end.
若是沒有匹配的斷言,則會拋出異常。所以最後一個斷言一般是true斷言。
Erlang中一切都是表達式,都有返回值,所以異常捕獲語句也有返回值。
捕獲全部的異常_:_
-module(learn_test). -author("ChenLiang"). %% API -export([catch_exc1/0,catch_exc2/0]). exception() -> exit({system, "123123"}). catch_exc1() -> try exception() catch _:_ -> 111 end. catch_exc2() -> try exception() catch _ -> 222 end.
erl shell輸出結果
1> learn_test:catch_exc1(). 111 2> learn_test:catch_exc2(). ** exception exit: {system,"123123"} in function learn_test:exception/0 (learn_test.erl, line 17) in call from learn_test:catch_exc2/0 (learn_test.erl, line 28)
多種錯誤的檢測能夠 使用try catch風格。
參考stackoverflow-How do I elegantly check many conditions in Erlang?
記得幫我點贊哦!
精心整理了計算機各個方向的從入門、進階、實戰的視頻課程和電子書,按照目錄合理分類,總能找到你須要的學習資料,還在等什麼?快去關注下載吧!!!
念念不忘,必有迴響,小夥伴們幫我點個贊吧,很是感謝。
我是職場亮哥,YY高級軟件工程師、四年工做經驗,拒絕鹹魚爭當龍頭的斜槓程序員。聽我說,進步多,程序人生一把梭
若是有幸能幫到你,請幫我點個【贊】,給個關注,若是能順帶評論給個鼓勵,將不勝感激。
職場亮哥文章列表:更多文章
本人全部文章、回答都與版權保護平臺有合做,著做權歸職場亮哥全部,未經受權,轉載必究!