青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

教父的告白
一切都是紙老虎
posts - 82,  comments - 7,  trackbacks - 0
ErLang語法中充滿了一些約定。大寫字母開頭的名字(比如Address),表示一個變量,包括參數、局部變量等;小寫字母開頭的單詞(比如ok),表示一個常量,叫做atom(原子的意思),包括常量名、函數名、模塊名等。

ErLang的注釋用%開頭。ErLang用下劃線“_”表示任意變量,類似于Java的switch語法里面的default選項。

ErLang脫胎于Prolog,不過,我覺得,ErLang語法和Haskell語法比較象,都是采用 -> 定義函數。

ErLang語句中的標點符號用法很象文章的標點符號。

整個函數定義結束用一個句號“.”;同一個函數中,并列的邏輯分支之間,用分號“;”分界;順序語句之間,用逗號“,”分隔。

ErLang中,{ }不是表示程序塊的開頭和結尾,而是表示一種特殊的數據結構類型——Tuple(元組),比如,{12, 3, ok}。我們可以把Tuple理解為定長數組。

[ ] 則表示最基本的函數式編程的數據結構類型——List。List數據結構很基本,寫法和用法也有一定的復雜度,不是表面上看起來那么簡單,后面講解Closure的章節會詳細介紹List的最基本的構造原理。

下面我們來看一個簡單的例子。

我們首先定義一個最簡單的函數,把一個參數乘以10,然后加1。
times10( Number ) –>
Temp = 10 * Number,
Temp + 1.

為了說明問題,上面的代碼把乘法操作和加法操作分成兩個步驟。Temp = 10 * Number語句后面是逗號,因為這是兩條順序執行的語句。Temp + 1語句后面是句號,表示整個函數定義結束。而且,可以看出,ErLang沒有return語句,最后執行的那條語句的執行結果就是返回值。

下面,我們把這個函數優化一下。當參數等于0的時候,直接返1;否則,就乘以10,然后加1,然后返回。這時候,我們就要用到case of邏輯分支語句,相當于java的switch語句。

times10( Number ) –>
case Number of
0 -> 1;
_ ->
Temp = 10 * Number,
Temp + 1
end.

我們來仔細觀察這段ErLang程序。

當Number等于0的時候,直接返回1。由于這是一條分支語句,和后面的分支是并列的關系,所以,1的后面的標點符號是分號。后面這個分支,下劃線“_”表示任何其它值,這里就表示除了1之外的任何其它數值。

需要注意的一點是,case of語句需要用end結尾,end之前不需要有標點符號。

上述代碼中的case of 語句,其實就是Pattern Match的一種。ErLang的Pattern Match很強大,能夠大幅度簡化程序邏輯,后面進行專門介紹。
Pattern Match
Pattern Match主要有兩個功能——比較分派和變量賦值。
其中,比較分派是最主要的功能。比較分派的意思是,根據參數值進行條件分支的分派。可以把比較分派功能看作是一種類似于if, else等條件分支語句的簡潔強大寫法。
上面的例子中,case Number of 就是根據Number的值進行比較分派。更常見的寫法是,可以把Pattern Match部分提到函數定義分支的高度。于是,上述代碼可以寫成下面的形式:
times10( 0 ) –> 1;
times10( Number ) –>
Temp = 10 * Number,
Temp + 1.

這段代碼由兩個函數定義分支構成,由于兩個函數分支的函數名相同,而且參數個數相同,而且兩個函數定義分支之間采用分號“;”分隔,說明這是同一個函數的定義。函數式編程語言中,這種定義方式很常見,看起來形式很整齊,宛如數學公式。

這段代碼的含義是,當參數值等于0的時候,那么,程序走第一個函數定義分支(即分號“;”結尾的“times10( 0 ) –> 1;”),否則,走下面的函數定義分支(即“times10( Number ) –>…”)。

第二個分支中的參數不是一個常數,而是一個變量Number,表示這個分支可以接受任何除了0之外的參數值,比如,1、2、12等等,這些值將賦給變量Number。
因此,這個地方也體現了Pattern Match的第二個功能——變量賦值。

Pattern Match的形式可以很復雜,下面舉幾個典型的例子。
(1)數據結構拆解賦值
前面將到了ErLang語言有一種相當于定長數組的Tuple類型,我們可以很方便地根據元素的位置進行并行賦值。比如,
{First, Second} = {1, 2}
我們還可以對復合Tuple數據結構進行賦值,比如
{A, {B, C}, D} = { 1, {2, 3}, 4 }
List數據結構的賦值也是類似。由于List的寫法和用法不是那么簡單,三言兩語也說不清楚,還徒增困擾,這里不再贅述。
(2)assertEquals語句
在Java等語言中,我們寫單元測試的時候,會寫一些assert語句,驗證程序運行結果。這些assert語句通常是以API的方式提供,比如,assertTrue()、assertEquals()等。
在ErLang中,可以用簡單的語句達到類似于assertTrue()、assertEquals()等API的效果。
比如,ErLang中,true = testA() 這樣的語句表示testA的返回結果必須是true,否則就會拋出異常。這個用法很巧妙。這里解釋一下。
前面講過,ErLang語法約定,小寫字母開頭的名字,都是常量名。這里的true自然也是一個常量,既然是常量,我們不可能對它賦值,那么true = testA()的意思就不是賦值,而是進行匹配比較。
(3)匹配和賦值同時進行
我們來看這樣一段代碼。
case Result of
{ok, Message} -> save(Message);
{error, ErrorMessage} -> log(ErrorMessage)
end.

這段代碼中,Result是一個Tuple類型,包含兩個元素,第一個元素表示成功(ok)或者失敗(error),第二個元素表示具體的信息。
可以看到,這兩個條件分支中,同時出現了常量和變量。第一個條件分支中的ok是常量,Message是變量;第二個條件分支中的error是常量,ErrorMessage是變量。
這兩個條件分支都既有比較判斷,也有變量賦值。首先,判斷ResultTuple中的第一個元素和哪一個分支的第一個元素匹配,如果相配,那么把ResultTuple中的第二個元素賦給這個分支的第二個變量元素。即,如果Result的第一個元素是ok,那么走第一個條件分支,并且把Result的第二個元素賦給Message變量;如果Result的第二個元素是error,那么走第二個條件分支,并且把Result的第二個元素賦給ErrorMessage變量。

在Java等語言中,實現上述的條件分支邏輯,則需要多寫幾條語句ErLang語法可以從形式上美化和簡化邏輯分支分派復雜的程序。
除了支持數相等比較,Pattern Match還可以進行范圍比較、大小比較等,需要用到關鍵字when,不過用到when的情況,就比if else簡潔不了多少,這里不再贅述。
匿名函數
ErLang允許在一個函數體內部定義另一個匿名函數,這是函數式編程的最基本的功能。這樣,函數式語言才可以支持Closure。我們來看一個ErLang的匿名函數的例子。
outer( C ) –>
Inner = fun(A, B) -> A + B + C end,
Inner(2, 3).

這段代碼首先定義了一個命名函數outer,然后在outer函數內部定義了一個匿名函數。可以看到,這個匿名函數采用關鍵字fun來定義。前面講過,函數式編程的函數就相當于面向對象編程的類實例對象,匿名函數自然也是這樣,也相當于類實例,我們可以把這個匿名函數賦給一個變量Inner,然后我們還可以把這個變量當作函數來調用,比如,Inner(2, 3)。
fun是ErLang用來定義匿名函數的關鍵字。這個關鍵字很重要。fun定義匿名函數的用法不是很復雜,和命名函數定義類似。
函數分支的定義也是類似,只是需要用end結尾,而不是用句號“.”結尾,而且fun只需要寫一次,不需要向命名函數那樣,每個分支都要寫。比如,
MyFunction = fun(0) -> 0;
(Number) -> Number * 10 + 1 end,
MyFunction(3),
函數作為變量
匿名函數可以當作對象賦給變量,命名函數同樣也可以賦給變量。具體用法還是需要借助重要的fun關鍵字。比如,
MyFunction = fun outer / 1

就可以把上述定義的outer函數賦給MyFunction變量。后面的 / 0表示這個outer函數只有一個參數。因為ErLang允許有多個同名函數的定義,只要參數個數不同,就是不同的函數。
我們可以看到,任何函數都可以作為變量,也可以作為參數和返回值傳來傳去,這些變量也可以隨時作為函數進行調用,于是就具有了一定的動態性。
函數的動態調用
ErLang有一個apply函數,可以動態調用某一個函數變量。
基本用法是 apply( 函數變量,函數參數列表 )。比如,上面的MyFunciton函數變量,就可以這么調用,apply( MyFunction, [ 5 ])。
那么我們能否根據一個字符串作為函數名獲取一個函數變量呢?這樣我們就可以根據一個字符串來動態調用某個函數了。
ErLang中,做到這一點很簡單。前面講過,函數名一旦定義了,自然就固定了,這也類似于常量名,屬于不可變的atom(原子)。所有的atom都可以轉換成字符串,也可以從字符串轉換過來。ErLang中的字符串實質上都是List。字符串和atom之間的轉換通過list_to_atom和atom_to_list來轉換。
于是我們可以這樣獲取MyFunciton:MyFunction = list_to_atom(“outer”)
如果outer函數已經定義,那么MyFucntion就等于outer函數,如果outer函數沒有定義,那么list_to_atom(“outer”)會產生一個新的叫做outer的atom,MyFucntion就等于這個新產生的atom。
如果需要強制產生一個已經存在的atom,那么我們需要調用list_to_existing_atom轉換函數,這個函數不會產生新的atom,而是返回一個已經存在了的atom。
Tuple作為數據成員集合
前面講解函數式編程特性的時候,提到了函數式編程沒有面向對象編程的成員變量,這是一個限制。
ErLang的Tuple類型可以一定程度克服這個限制。Tuple可以一定程度上擔當容納成員變量的職責。
面向對象的類定義,其實就是一群數據和函數的集合,只是集合的成員之間都有一個this指針相關聯,可以相互找到。
ErLang的Tuple類型就是數據的集合,可以很自然地發揮成員變量的作用,比如,{Member1, Member2}。
讀者可能會說,ErLang的函數也可以作為變量,也可以放到Tuple里面,比如, { Memer1, Member2, Funtion1, Function2}。這不就和面向對象編程一樣了嗎?
遺憾的是,這樣做是得不償失的。因為函數式編程沒有面向對象的那種內在的this指針支持,自然也沒有內在的多態和繼承支持,硬把數據和函數糅合在一個Tuple里面,一點好處都沒有,而且還喪失了函數作為實例對象的靈活性。
所以,函數式編程的最佳實踐(Best Practice)應該是:Tuple用來容納成員數據,函數操作Tuple。Tuple定義和函數定義加在一起,就構成了松散的數據結構,功能上類似于面向對象的類定義。Tuple + 函數的數據結構,具有多態的特性,因為函數本身能夠作為變量替換;但是不具有繼承的特性,因為沒有this指針的內在支持。
正是因為Tuple在數據類型構造方面的重大作用,所以,ErLang專門引入了一種叫做Record的宏定義,可以對Tuple的數組下標位置命名。比如,把第一個元素叫做Address,第二個元素叫做Zipcode,這樣程序員就可以這些名字訪問Tuple里面的元素,而不需要按照數組下標位置來訪問。
Tuple和Record的具體用法還是有一定復雜度,限于篇幅,本章沒有展開說明,只提了一些原理方面的要點。
其它
ErLang還有其它語法特性和細節,不再一一贅述。有興趣的讀者,可以自行去ErLang網站(www.erlang.org)進行研究。
posted on 2009-09-11 11:04 暗夜教父 閱讀(738) 評論(0)  編輯 收藏 引用 所屬分類: erlang

<2009年9月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用鏈接

留言簿(2)

隨筆分類

隨筆檔案

文章分類

文章檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产一区91| 亚洲国产精品一区二区www| 欧美电影免费观看网站| 久久精品日韩欧美| 久久精品男女| 奶水喷射视频一区| 欧美久久久久久久| 国产精品一区=区| 亚洲一二区在线| 亚洲欧美日韩精品久久| 亚洲一区二区免费在线| 午夜亚洲精品| 蜜臀va亚洲va欧美va天堂| 欧美大秀在线观看| 国产精品每日更新| 好吊日精品视频| 亚洲精品一区二区网址| 亚洲欧美日韩国产一区二区三区| 久久久久综合网| 亚洲久久一区二区| 久久精品国语| 欧美午夜视频网站| 亚洲第一区色| 亚洲欧美文学| 亚洲国产三级| 久久国产精品久久久久久| 欧美国产综合| 国外成人免费视频| 亚洲影视九九影院在线观看| 开心色5月久久精品| 国产精品99久久久久久久久| 久久婷婷国产综合精品青草| 国产精品久久久久久久久久免费看| 精品成人在线视频| 亚洲男人影院| 亚洲日本视频| 久久亚洲国产成人| 国产日产精品一区二区三区四区的观看方式 | 日韩午夜在线播放| 国产日产欧美a一级在线| 亚洲成色www8888| 亚洲欧美激情四射在线日 | 国产在线播放一区二区三区| 91久久国产综合久久| 久久精品国产77777蜜臀| 中文精品视频一区二区在线观看| 美女视频一区免费观看| 一区精品久久| 久久久亚洲高清| 午夜精品久久久久久久99樱桃| 欧美日韩亚洲一区二区三区在线| 亚洲国产婷婷综合在线精品 | 欧美成年人视频网站| 香蕉av福利精品导航| 欧美性视频网站| 中文av字幕一区| 亚洲狼人综合| 欧美日本不卡| 亚洲美女av黄| 亚洲日本aⅴ片在线观看香蕉| 久久尤物电影视频在线观看| 黄色成人av网站| 免费欧美在线视频| 蜜乳av另类精品一区二区| 尤物yw午夜国产精品视频明星| 久久av资源网站| 久久国产精品久久精品国产| 国内精品久久久久久| 久久久国产精品亚洲一区| 亚洲欧美日本另类| 韩国成人精品a∨在线观看| 久久久水蜜桃av免费网站| 欧美韩国日本综合| 欧美福利一区二区三区| 99国产精品视频免费观看一公开| 最新亚洲一区| 欧美亚一区二区| 久久se精品一区精品二区| 久久国产精品一区二区三区| 在线日韩一区二区| 亚洲裸体视频| 国产欧美一区二区精品性| 欧美成熟视频| 国产精品videosex极品| 久久久久www| 欧美1级日本1级| 在线亚洲自拍| 欧美一区影院| 亚洲清纯自拍| 亚洲欧美日韩精品久久久| 亚洲福利视频网站| 在线视频日韩精品| 在线观看一区二区精品视频| 亚洲精品色图| 免费成人在线观看视频| 欧美日韩国产区| 久久se精品一区二区| 欧美成人午夜激情视频| 亚洲欧美日韩综合一区| 久久在线免费| 亚洲欧美第一页| 美女日韩在线中文字幕| 欧美中文字幕不卡| 欧美精品一区二区蜜臀亚洲| 欧美一区二区在线观看| 欧美国产日韩精品| 久久青青草原一区二区| 欧美日韩综合| 亚洲成人在线视频播放 | 99综合精品| 国产精品99久久久久久有的能看 | 亚洲人成在线观看| 国产午夜精品一区理论片飘花| 最新高清无码专区| 尤物网精品视频| 亚洲在线成人| 在线亚洲自拍| 欧美激情亚洲| 欧美1区2区| 国产一区二区三区高清在线观看 | 夜夜精品视频| 亚洲精品无人区| 久久久www免费人成黑人精品| 亚洲天堂成人在线视频| 欧美激情成人在线视频| 欧美a级一区二区| 国内精品**久久毛片app| 亚洲欧美日韩在线高清直播| 一区二区三区产品免费精品久久75 | 亚洲男人的天堂在线aⅴ视频| 亚洲毛片网站| 欧美激情一区二区三区四区 | 欧美激情欧美激情在线五月| 国产日韩综合一区二区性色av| 一本色道久久99精品综合| 一区二区欧美精品| 国产精品成人免费| 在线一区二区三区四区五区| 亚洲精品免费观看| 欧美一级视频| 久久久免费精品视频| 国产日韩专区| 久久久久亚洲综合| 免费亚洲一区二区| 在线视频你懂得一区二区三区| 欧美日韩高清在线播放| 亚洲第一中文字幕在线观看| 影音先锋成人资源站| 久久综合影音| 亚洲国产激情| 在线亚洲伦理| 国产精品人成在线观看免费 | 久久日韩粉嫩一区二区三区| 国产亚洲综合性久久久影院| 久久国产精品久久久久久| 欧美成人xxx| 一本久久综合亚洲鲁鲁五月天| 欧美午夜精品一区| 欧美一区二区三区在| 蜜臀av一级做a爰片久久| 亚洲乱码国产乱码精品精98午夜| 欧美日韩国产在线看| 午夜精彩国产免费不卡不顿大片| 久久精品天堂| 亚洲精品无人区| 国产日韩高清一区二区三区在线| 久久久久网址| 亚洲性感美女99在线| 看片网站欧美日韩| 亚洲视频二区| 永久免费毛片在线播放不卡| 欧美日韩国产专区| 久久免费视频网站| 亚洲天堂偷拍| 亚洲欧洲精品一区二区三区不卡| 午夜精品久久久久久| 亚洲国产91色在线| 国产精品一级久久久| 欧美激情aaaa| 久久精品免费观看| 国产亚洲午夜| 午夜亚洲伦理| 亚洲精品久久久久中文字幕欢迎你 | 亚洲人在线视频| 久久久夜色精品亚洲| 亚洲性夜色噜噜噜7777| 亚洲高清一区二| 国产日韩一区二区| 欧美日韩美女| 欧美成人免费全部观看天天性色| 亚洲女人天堂成人av在线| 亚洲精品视频一区二区三区| 久久伊伊香蕉| 久久黄色网页| 欧美一级专区免费大片| 亚洲午夜影视影院在线观看| 亚洲久久一区| 亚洲日本在线视频观看| 亚洲电影在线免费观看| 怡红院av一区二区三区|