Elixir初體驗(yàn)

在京東上搜Elixir向楼,會(huì)發(fā)現(xiàn)Elixir是一種琴弦的品牌查吊,然而我今天想講的Elixir是一種編程語(yǔ)言。它的Logo如下

Elixir

早就有學(xué)習(xí)這門語(yǔ)言的打算湖蜕,只是事情太多逻卖,忙著忙著就忘了。公司最近的技術(shù)分享中重荠,明哥分享了一個(gè)關(guān)于Phoenix(基于Elixir的Web開(kāi)發(fā)框架)跟Rails的比較的話題箭阶,重新燃起了我對(duì)這門語(yǔ)言的好奇心。接下來(lái)讓我們一起簡(jiǎn)單的來(lái)看看Elixir這門語(yǔ)言戈鲁。

1. Elixir是什么

我們先來(lái)看看官方的解釋

Elixir is a dynamic, functional language designed for building scalable and maintainable applications.

Elixir 是一門動(dòng)態(tài)的函數(shù)式編程語(yǔ)言,主要是用來(lái)構(gòu)建可擴(kuò)展嘹叫,可維護(hù)的應(yīng)用程序婆殿。好吧,把函數(shù)式去掉的話Ruby也可以做到罩扇。Ruby是一門動(dòng)態(tài)的命令式編程語(yǔ)言婆芦,可以用來(lái)構(gòu)建可擴(kuò)展及可維護(hù)的應(yīng)用程序怕磨。不過(guò)Ruby設(shè)計(jì)的初衷并不是為了解決什么問(wèn)題,它的初衷是Happy Coding!

Elixir leverages the Erlang VM, known for running low-latency, distributed and fault-tolerant systems, while also being successfully used in web development and the embedded software domain.

Elixir運(yùn)行在Erlang虛擬機(jī)上消约,以低負(fù)載肠鲫,分布式和容錯(cuò)系統(tǒng)而聞名。已經(jīng)成功應(yīng)用在Web開(kāi)發(fā)領(lǐng)域或粮,以及嵌入式軟件領(lǐng)域导饲。這也算是編程語(yǔ)言的另一個(gè)發(fā)展方向吧,除了直接用系統(tǒng)級(jí)編程語(yǔ)言(如C氯材,C++渣锦,Go)來(lái)開(kāi)發(fā)編程語(yǔ)言,我們還可以在比較成熟的虛擬系統(tǒng)上構(gòu)造我們想要的編程語(yǔ)言氢哮。比如JavaVM之上有人發(fā)明了Clojure袋毙,Scale這些函數(shù)式編程語(yǔ)言(身邊的人好像比較喜歡Clojure),而有位Ruby英雄在ErlangVM上實(shí)現(xiàn)了Elixir冗尤。

2. 安裝Elixir

安裝教程沒(méi)有能比官方文檔更加詳細(xì)的了听盖,我這里就不重復(fù)說(shuō)了,我就說(shuō)說(shuō)我在Mac上安裝的時(shí)候遇到的比較尷尬的問(wèn)題吧裂七。

Elixir是運(yùn)行在Erlang環(huán)境下的編程語(yǔ)言媳溺,當(dāng)我們用HomeBrew安裝Elixir的時(shí)候,它也會(huì)順勢(shì)幫你安裝Erlang碍讯。

想想很久之前我們用HomeBrew安裝了Elixir悬蔽,以及配套的Erlang環(huán)境。然后我們卸載了Elixir捉兴,卻留下了Erlang蝎困。幾個(gè)月后我們重新安裝Elixir這個(gè)時(shí)候,也配套安裝了最新版本的Erlang倍啥,于是事故發(fā)生了禾乘。

兩個(gè)不同版本的Erlang
> erl
Erlang/OTP 19 [erts-8.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Eshell V8.3  (abort with ^G)
1>

我們的系統(tǒng)同時(shí)保留著兩個(gè)版本的Erlang,以及新版本的Elixir虽缕。而系統(tǒng)還默認(rèn)引用這舊版本的Erlang始藕,這表明了我們會(huì)把新版本的Elixir運(yùn)行在舊版本的Erlang上面,你可能就會(huì)得到如下錯(cuò)誤氮趋。

> iex
2017-11-02 21:54:29 Loading of ~ts failed: ~p

    "/usr/local/Cellar/elixir/1.5.2/bin/../lib/iex/ebin/Elixir.IEx.CLI.beam"
    badfile
2017-11-02 21:54:29 ~s~n
    "beam/beam_load.c(1287): Error loading module 'Elixir.IEx.CLI':\n  mandatory chunk of type 'Atom' not found\n\n"
2017-11-02 21:54:29 crash_report
    initial_call: {supervisor_bridge,user_sup,['Argument__1']}
    pid: <0.47.0>
    registered_name: []
    error_info: {exit,{undef,[{'Elixir.IEx.CLI',start,[],[]},{user_sup,start_user,3,[{file,"user_sup.erl"},{line,100}]},{user_sup,init,1,[{file,"user_sup.erl"},{line,49}]},{supervisor_bridge,init,1,[{file,"supervisor_bridge.erl"},{line,80}]},{gen_server,init_it,6,[{file,"gen_server.erl"},{line,328}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]},[{gen_server,init_it,6,[{file,"gen_server.erl"},{line,352}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]}
    ancestors: [kernel_sup,<0.34.0>]
    messages: []
    links: [<0.35.0>]
    dictionary: []
    trap_exit: true
    status: running
    heap_size: 610
    stack_size: 27
    reductions: 145
2017-11-02 21:54:29 supervisor_report
    supervisor: {local,kernel_sup}
    errorContext: start_error
    reason: {undef,[{'Elixir.IEx.CLI',start,[],[]},{user_sup,start_user,3,[{file,"user_sup.erl"},{line,100}]},{user_sup,init,1,[{file,"user_sup.erl"},{line,49}]},{supervisor_bridge,init,1,[{file,"supervisor_bridge.erl"},{line,80}]},{gen_server,init_it,6,[{file,"gen_server.erl"},{line,328}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]}
    offender: [{pid,undefined},{id,user},{mfargs,{user_sup,start,[]}},{restart_type,temporary},{shutdown,2000},{child_type,supervisor}]
2017-11-02 21:54:29 crash_report
    initial_call: {application_master,init,['Argument__1','Argument__2','Argument__3','Argument__4']}
    pid: <0.33.0>
    registered_name: []

這是個(gè)錯(cuò)誤示范伍派,可能你也會(huì)遇到類似的問(wèn)題,報(bào)錯(cuò)信息不會(huì)完全一樣剩胁,不過(guò)應(yīng)該也差不多诉植。究其原因就如上面所說(shuō)Eixir版本跟Erlang版本不兼容,當(dāng)我們想在老版本的Erlang上跑新版本的Elixir就出問(wèn)題了昵观。

解決方法有兩個(gè)

1) 切換Erlang的默認(rèn)版本晾腔,換成我們期待的最新版本的Erlang

我們通過(guò)HomeBrew的命令

brew switch erlang 20.1.3

只需要簡(jiǎn)單地把默認(rèn)Erlang運(yùn)行環(huán)境指定到我們需要的最新版本的舌稀,然后重新運(yùn)行Elixir就能夠進(jìn)入我們期待的REPL環(huán)境了。

> iex
Erlang/OTP 20 [erts-9.1.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help)

2) 卸載Elixir灼擂,以及所有版本的Erlang壁查,重新安裝

這種方法簡(jiǎn)單粗暴,如果我們不需要多版本的Erlang的話我建議可以把他們都移除掉剔应,畢竟一個(gè)Erlang包會(huì)占用掉系統(tǒng)200多MB的磁盤空間睡腿。

通過(guò)brew命令的uninstall指令,加上--force標(biāo)識(shí)就能夠移除所有版本的Erlang

brew uninstall --force erlang

如果單獨(dú)移除Erlang而不移除Elixir的話就會(huì)有以下的異常信息

Error: Refusing to uninstall /usr/local/Cellar/erlang/20.1.3
because it is required by elixir 1.5.2, which is currently installed.
You can override this and force removal with:
  brew uninstall --ignore-dependencies erlang

前面也說(shuō)了Elixir依賴于Erlang领斥,當(dāng)我們只想單獨(dú)卸載被依賴的Erlang的時(shí)候就會(huì)有這個(gè)警告嫉到,我不建議用它的命令保留Elixir而單獨(dú)移除Erlang,畢竟該清理的還是要清理干凈月洛,重新安裝也耗費(fèi)不了多少時(shí)間何恶。我們只需要依次運(yùn)行以下命令

brew uninstall elixir
brew uninstall --force erlang
brew install elixir

把Elixir以及所有版本的Erlang刪除之后,再重新安裝Elixir嚼黔,我們就可以體驗(yàn)最新版本的Elixir细层,并開(kāi)始美妙的Elixir之旅。

> iex
Erlang/OTP 20 [erts-9.1.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help)

3. 第一條Elixir程序

又到了大家喜聞樂(lè)見(jiàn)的活動(dòng)了唬涧,第一條程序總是會(huì)讓人熱血沸騰疫赎。不過(guò)咱門今天就別上HelloWorld了吧,來(lái)簡(jiǎn)單寫一個(gè)腳本碎节。

First

(1) 編譯模式

寫習(xí)慣了解釋性語(yǔ)言捧搞,已經(jīng)很久沒(méi)試過(guò)編譯代碼了。想想以前寫C的時(shí)候運(yùn)行之前都是需要先編譯狮荔,然后執(zhí)行生成的二進(jìn)制文件√テ玻現(xiàn)在我們來(lái)看看Elixir是如何操作的。

Elixir有個(gè)約定殖氏,需要編譯的文件以.ex后綴名結(jié)尾晚树,而直接運(yùn)行的腳本則.exs后綴名結(jié)尾,我們也依照這個(gè)約定吧(即便我們都知道在Unix操作系統(tǒng)里面后綴名是什么根本就無(wú)所謂)雅采。這里我們創(chuàng)建一個(gè)文件math.ex

# math.ex

defmodule Math do
  def sum(a, b) do
    a + b
  end
end

這種編碼風(fēng)格跟Ruby很像爵憎,實(shí)際上我們定義了一個(gè)包含sum方法的模塊Math,然后運(yùn)行編譯命令

> elixirc math.ex

編譯成功后會(huì)生成名為Elixir.Math.beam的文件

> ls
Elixir.Math.beam math.ex

這個(gè)就是編譯后的字節(jié)碼文件婚瓜,熟悉Java的人應(yīng)該知道Java里面也有類似的存在宝鼓。然后我們?cè)诋?dāng)前目錄下面運(yùn)行iex進(jìn)行REPL環(huán)境,就能直接使用這個(gè)Math模塊了

> iex
Erlang/OTP 20 [erts-9.1.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Math.sum(1,2)
3

接下來(lái)再簡(jiǎn)單看看腳本模式闰渔。

(2) 腳本模式

每次都要編譯那多麻煩啊席函,很好浸策,這也是我不喜歡部分編譯型語(yǔ)言的原因之一(只是部分)---它們甚至連REPL環(huán)境都沒(méi)有灿椅。Elixir考慮到了這一點(diǎn),按照習(xí)俗我們?cè)谛履夸浵聞?chuàng)建一個(gè)math.exs的腳本文件

# math.exs

defmodule Math do
  def sum(a, b) do
    a + b
  end
end

PS: 內(nèi)容跟編譯模式中的文件一樣抚太,只是后綴名不同督弓。

> ls
math.exs

然后我們可以直接用相關(guān)的命令運(yùn)行對(duì)應(yīng)腳本

> elixir math.exs

由于我們math.exs里面只是定義了一個(gè)簡(jiǎn)單的模塊和方法营曼,并沒(méi)有更多的邏輯,所以這次執(zhí)行也看不出什么效果愚隧。不過(guò)在Elixir機(jī)制中我們可以像下面這樣操作蒂阱,直接地把目標(biāo)文件加載到REPL環(huán)境中

> iex math.exs
Erlang/OTP 20 [erts-9.1.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Math.sum(1,2)
3

可以看到運(yùn)行結(jié)果跟之前編譯模式一樣的只是少了手動(dòng)編譯那一步,這有利于我們對(duì)源碼文件進(jìn)行簡(jiǎn)單地測(cè)試狂塘,而不需要每次測(cè)試的時(shí)候都手動(dòng)編譯一次录煤。

官網(wǎng)的建議是平時(shí)開(kāi)發(fā)業(yè)務(wù)邏輯代碼都以.ex后綴名結(jié)尾,最后需要被編譯成字節(jié)碼(這可能是性能方面考慮吧)荞胡。而編寫日常單元測(cè)試或者配置信息則以.exs后綴名來(lái)結(jié)尾妈踊。

4. 總結(jié)

對(duì)這門語(yǔ)言的學(xué)習(xí),大概只是看了4-5天的入門指南泪漂。它是否真如文檔所說(shuō)能夠用來(lái)構(gòu)建可擴(kuò)展性高的系統(tǒng)廊营,以及它是否真的有傳聞?wù)f的那樣地高性能呢?這一點(diǎn)還有待考證萝勤。

剁手

不過(guò)經(jīng)過(guò)這兩天的學(xué)習(xí)露筒,我覺(jué)得這是一門挺值得入手的語(yǔ)言,特別是對(duì)于Ruby系的朋友來(lái)說(shuō)敌卓。如果說(shuō)Haskell是有Python風(fēng)格的純函數(shù)式編程語(yǔ)言(他們大寫的None讓我印象深刻)慎式,那我覺(jué)得Elixir就是有Ruby風(fēng)格的函數(shù)式編程語(yǔ)言了。不過(guò)即便它語(yǔ)法風(fēng)格設(shè)計(jì)方面跟Ruby很像趟径,但Elixir就是Elixir瘪吏,相信你會(huì)從中感受到與Ruby不一樣的編程體驗(yàn)。

Happy Coding and Writing!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末舵抹,一起剝皮案震驚了整個(gè)濱河市肪虎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惧蛹,老刑警劉巖扇救,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異香嗓,居然都是意外死亡迅腔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門靠娱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沧烈,“玉大人,你說(shuō)我怎么就攤上這事像云⌒咳福” “怎么了蚂夕?”我有些...
    開(kāi)封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)腋逆。 經(jīng)常有香客問(wèn)我婿牍,道長(zhǎng),這世上最難降的妖魔是什么惩歉? 我笑而不...
    開(kāi)封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任等脂,我火速辦了婚禮,結(jié)果婚禮上撑蚌,老公的妹妹穿的比我還像新娘上遥。我一直安慰自己,他們只是感情好争涌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布粉楚。 她就那樣靜靜地躺著,像睡著了一般第煮。 火紅的嫁衣襯著肌膚如雪解幼。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天包警,我揣著相機(jī)與錄音撵摆,去河邊找鬼。 笑死害晦,一個(gè)胖子當(dāng)著我的面吹牛特铝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播壹瘟,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼鲫剿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了稻轨?” 一聲冷哼從身側(cè)響起灵莲,我...
    開(kāi)封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎殴俱,沒(méi)想到半個(gè)月后政冻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡线欲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年明场,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片李丰。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡苦锨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舟舒,我是刑警寧澤拉庶,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站魏蔗,受9級(jí)特大地震影響砍的,放射性物質(zhì)發(fā)生泄漏痹筛。R本人自食惡果不足惜莺治,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帚稠。 院中可真熱鬧谣旁,春花似錦、人聲如沸滋早。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)杆麸。三九已至搁进,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昔头,已是汗流浹背饼问。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揭斧,地道東北人莱革。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像讹开,于是被迫代替她去往敵國(guó)和親盅视。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容