日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
神奇的仙丹,性感的Elixir

在IT世界里,沒(méi)有銀彈,但卻有神奇的仙丹(Elixir)。我不知道是什么靈感刺激這門(mén)語(yǔ)言的創(chuàng)造者José Valim想到了這么酷的命名,但這枚仙丹確實(shí)經(jīng)由多種神奇的靈藥煉制而成,這些靈藥包括Erlang、Ruby、Clojure、Haskell。

創(chuàng)新互聯(lián)建站于2013年成立,先為神農(nóng)架林區(qū)等服務(wù)建站,神農(nóng)架林區(qū)等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢(xún)服務(wù)。為神農(nóng)架林區(qū)企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

品嘗這枚仙丹確實(shí)令人飄飄欲仙,至少,我在淺嘗Elixir時(shí),這種奇妙的感覺(jué)一直縈繞在我心間,怦然心動(dòng)因而不舍離去。或許如Erlang之父Joe Armstrong所說(shuō),是“一種先行于邏輯的內(nèi)心感性的感覺(jué)”;又或者如Dave Thomas形容的,那是讓人“墜入愛(ài)河”的感覺(jué)。

大愛(ài)Elixir。

我之所以愛(ài)上Elixir,大約還是因?yàn)镽uby的緣故。我并非Ruby的狂熱追隨者,甚至沒(méi)有從事太多Ruby相關(guān)的項(xiàng)目,但我至今在編寫(xiě)腳本時(shí),Ruby依舊是我的首選。在動(dòng)態(tài)語(yǔ)言中,我甚喜愛(ài)Ruby相對(duì)簡(jiǎn)潔的語(yǔ)法。當(dāng)我看到Elixir時(shí),那種似曾相識(shí)的感覺(jué)讓我心動(dòng)。

雖然說(shuō)Elixir的煉制來(lái)自各位前輩留下的丹方靈藥,然而從成丹之日起,Elixir就是Elixir,她已經(jīng)具有了完整的語(yǔ)言性格。就我看來(lái),Elixir真正稱(chēng)得上是“性感”。當(dāng)然,這一大半要?dú)w功于Erlang美麗的英倫風(fēng)情(Erlang之父Joe Armstrong是英國(guó)人),就Erlang的高顏值打底,只需再加上幾點(diǎn)嫵媚,幾分妖嬈,風(fēng)采就變得性感撩人了。

并發(fā)與分布式

Elixir對(duì)并發(fā)與分布式的支持,就是正宗的英倫風(fēng)情,這是從Erlang延續(xù)下來(lái)的最強(qiáng)悍基因。Elixir建立在Erlang虛擬機(jī)(BEAM)之上,使用Erlang的進(jìn)程,如原生進(jìn)程那樣在所有的處理器中運(yùn)行,然而開(kāi)銷(xiāo)卻非常小。與Erlang一樣,Elixir可以通過(guò)spawn輕松地創(chuàng)建進(jìn)程:

 
 
  1. spawn fn -> 1 + 2 end 

Elixir或者說(shuō)Erlang的進(jìn)程依靠消息傳遞完成通信。進(jìn)程接收到的消息實(shí)際上是獲取的一份消息副本,這就使得接收方能夠與發(fā)送方解耦,接收方對(duì)消息的任何操作不會(huì)影響接收方。

 
 
  1. send self, {:hello, "world"}receive do 
  2. {:hello, msg} -> msg 
  3. {:world, msg} -> "won't match" 
  4. end 

Elixir的核心繼承自Erlang,自然就繼承了對(duì)OTP(Open Telecom Platform)的支持。OTP是一個(gè)很大的課題,包括進(jìn)程鏈接、監(jiān)控以及分布式支持(我正在學(xué)習(xí)《Erlang/OTP并發(fā)編程實(shí)戰(zhàn)》,希望從Erlang根源上理解OTP)。Elixir對(duì)OTP的支持包括Agent、Task、GenServer以及Supervisor與Application。其中,Agent與Task是Elixir對(duì)OTP特性的抽象,而GenServer則更加通用。

在Elixir創(chuàng)建OTP服務(wù)器非常簡(jiǎn)單,只需要use GenServer即可。它主要的方法為handle_call(request, from, state)與handle_cast(request, state)。如果客戶(hù)端發(fā)送的請(qǐng)求需要響應(yīng)時(shí),則消息形式為call,如果為單向調(diào)用,則形式為cast。

考慮進(jìn)程的健壯性問(wèn)題,在編寫(xiě)OTP應(yīng)用時(shí),可能還需要對(duì)進(jìn)程進(jìn)行監(jiān)督?;贏ctor模型,父進(jìn)程將負(fù)責(zé)監(jiān)督由其創(chuàng)建的所有子進(jìn)程,下面的代碼是Elixir官方提供的Supervisor代碼:

 
 
  1. defmodule KV.Supervisor do 
  2.   use Supervisor 
  3.  
  4.   def start_link do 
  5.     Supervisor.start_link(__MODULE__, :ok) 
  6.   end 
  7.  
  8.   def init(:ok) do 
  9.     children = [ 
  10.         worker(KV.Registry, [KV.Registry]), 
  11.         supervisor(KV.Bucket.Supervisor, []) 
  12.     ] 
  13.  
  14.     supervise(children, strategy: :rest_for_one) 
  15.   end 
  16. end 

KV.Supervisor為監(jiān)督進(jìn)程,其子進(jìn)程分別為KV.Registry與KV.Bucket.Supervisor,監(jiān)督策略為rest_for_one。

至于分布式支持,在Elixir其實(shí)是水到渠成的事情,因?yàn)樗暮诵氖沁M(jìn)程間通信,而進(jìn)程所在的節(jié)點(diǎn)位置,對(duì)于用戶(hù)而言是透明的。

模式匹配

模式匹配是Elixir最妖嬈的部分,雖然很多函數(shù)式語(yǔ)言都有模式匹配,但Elixir卻把模式匹配融入到其血肉之中(其實(shí)是延續(xù)了Erlang的模式匹配特色)。即使是一個(gè)賦值語(yǔ)句,也是模式匹配的一部分。在Elixir中,=符號(hào)其實(shí)被稱(chēng)之為匹配運(yùn)算符(match operator)。所以你可以寫(xiě)出違反程序員常規(guī)的1 = x:

 
 
  1. iex> 1 = x 
  2. iex> 2 = x 
  3. ** (MatchError) no match of right hand side value: 1 

模式匹配在Elixir中被廣泛地運(yùn)用到解構(gòu)(destructuring )復(fù)雜的數(shù)據(jù)結(jié)構(gòu),例如Tuple、List等。當(dāng)然case進(jìn)行的模式匹配更是它最常見(jiàn)的使用場(chǎng)景。

函數(shù)與模式匹配的結(jié)合才是體現(xiàn)妖嬈性的關(guān)鍵點(diǎn),如果再結(jié)合guard clause,那就真正讓人銷(xiāo)魂了。

大多數(shù)語(yǔ)言的函數(shù)定義是支持函數(shù)重載的,這取決于參數(shù)的類(lèi)型、個(gè)數(shù)與順序。在動(dòng)態(tài)語(yǔ)言中沒(méi)有類(lèi)型,則與個(gè)數(shù)與順序相關(guān)。這些參數(shù)在定義時(shí)皆為形參(部分語(yǔ)言支持默認(rèn)參數(shù)值,Elixir也支持,甚至可以將表達(dá)式作為默認(rèn)參數(shù)),在調(diào)用時(shí)才傳入實(shí)參。

但是,Elixir則不然,因?yàn)镋lixir沒(méi)有賦值的概念,因此在傳遞參數(shù)時(shí),并非賦值的語(yǔ)義,而是匹配的語(yǔ)義。因而出現(xiàn)如下的函數(shù)定義,你不要感到詫異哦:

 
 
  1. defmodule Factorial do 
  2.     def of(0), do: 1 
  3.     def of(n), do: n * of(n-1)  
  4. end 

在Elixir語(yǔ)義中,這兩個(gè)定義實(shí)則是同一個(gè)函數(shù),當(dāng)調(diào)用of函數(shù)時(shí),傳入的參數(shù)會(huì)與第一個(gè)定義進(jìn)行匹配,如果匹配不成功,則匹配第二個(gè)定義。利用這種模式匹配,既可以規(guī)避實(shí)現(xiàn)上的if分支,又可以更好地體現(xiàn)遞歸的語(yǔ)義。

Meyer非常強(qiáng)調(diào)軟件開(kāi)發(fā)中對(duì)“契約”的遵循,在他設(shè)計(jì)的語(yǔ)言Eiffel中,前置條件與后置條件作為了語(yǔ)法糖中的一等公民被支持。Erlang的guard Cluase與Eiffel的前置條件非常相似,Elixir也保留了這一語(yǔ)法特性。例如在前面的階乘算法中,我們可以通過(guò)guard clause避免傳入錯(cuò)誤的負(fù)數(shù):

 
 
  1. defmodule Factorial do 
  2.     def of(0), do: 1 
  3.     def of(n) when n > 0, do: n * of(n-1) 
  4. end 

管道運(yùn)算符

讓Elixir展現(xiàn)其嫵媚一面的,是超級(jí)性感的管道運(yùn)算符。她讓整段代碼瞬間變得可愛(ài)起來(lái)。有了她,我們就不用再陷入可怕的函數(shù)嵌套地獄中了。Dave Long在博文Playing with Elixir Pipes中給出了一個(gè)頗有對(duì)照意義的例子。代碼功能是從conn取得Request的header,并判斷它是否有效。如果有效就返回conn,否則終止,并返回Not Authorized。

如果沒(méi)有管道運(yùn)算符,就得承受嵌套函數(shù)調(diào)用的驚悚感:

 
 
  1. signature = List.first(get_req_header(conn, "x-twilio-signature"))   
  2. is_valid = Validator.validate(url_from_conn(conn), conn.params, signature)   
  3. if is_valid do   
  4.   conn 
  5. else   
  6.   halt(send_resp(conn, 401, "Not authorized")) 
  7. end 

這樣的代碼完全違反人類(lèi)直覺(jué)的,因?yàn)槟愕脧暮瘮?shù)最里邊閱讀,然后再層層往外逃逸。是否有一種被緊緊捆綁了的感覺(jué)呢?當(dāng)然,在很多語(yǔ)言中我們都無(wú)奈地接受了這一點(diǎn),已經(jīng)被虐得習(xí)以為常了。嘗試一下管道運(yùn)算符,會(huì)怎么樣?

 
 
  1. signature = conn   
  2.             |> get_req_header("x-twilio-signature") 
  3.             |> List.first 
  4. if conn   
  5.    |> url_from_conn 
  6.    |> Validator.validate(conn.params, signature) 
  7. do   
  8.   conn 
  9. else   
  10.   conn |> send_resp(401, "Not authorized") |> halt 
  11. end 

當(dāng)你把管道運(yùn)算符|>看成是goto的話(huà),我們就能直觀地體會(huì)到conn在各個(gè)函數(shù)中流動(dòng)的現(xiàn)象了。非??蓯?ài),不是嗎?

Elixir是純正的函數(shù)式語(yǔ)言,本質(zhì)上講,Elixir中的一切皆為函數(shù),所以if表達(dá)式其實(shí)也是函數(shù)。這就意味著validate后的布爾結(jié)果可以通過(guò)|>直接傳遞給if:

 
 
  1. signature = conn   
  2.             |> get_req_header("x-twilio-signature") 
  3.             |> List.first 
  4. conn   
  5. |> url_from_conn 
  6. |> Validator.validate(conn.params, signature) 
  7. |> if(do: conn, else: conn |> send_resp(401, "Not authorized") |> halt) 

這才是真正Elixir Style的編程范兒,夠嫵媚吧!

Joe Armstrong認(rèn)為管道運(yùn)算符來(lái)自Prolog語(yǔ)言的隱性基因DCG,類(lèi)似Haskell中的monad。Prolog的兒子erlang沒(méi)有體現(xiàn)這一點(diǎn),孫子輩又隔代遺傳上了。

工程支持

Elixir的創(chuàng)造者José Valim乃Rails的核心參與者,所以他把Rails社區(qū)(包括Ruby社區(qū))中一套讓人目眩的工程實(shí)踐照般過(guò)來(lái)了。

腳手架

通過(guò)mix可以直接幫助我們創(chuàng)建項(xiàng)目的腳手架(用過(guò)rails的童鞋感到親切了嗎?):

mix new myproject

執(zhí)行這條命令,mix就會(huì)幫我們創(chuàng)建項(xiàng)目的基本結(jié)構(gòu)和相應(yīng)文件:

包管理與依賴(lài)管理

通過(guò)Hex來(lái)管理包(記得GEM嗎?)。在http://hex.pm中幾乎可以找到所有你想要的elixir包;當(dāng)然你還可以享受Erlang的福利,直接重用erlang包。

添加依賴(lài)也非常方便,只需要在項(xiàng)目的mix.exs文件中添加依賴(lài)即可。例如添加HTTPoison和JSX包的依賴(lài):

 
 
  1. defp deps do 
  2.    [ 
  3.      {:httpoison, "~> 0.11.0"}, 
  4.      {:jsx, "~> 2.8"} 
  5.    ] 
  6.  end 

最棒的是,Elixir還支持直接對(duì)github repository的依賴(lài)。

環(huán)境配置

對(duì)開(kāi)發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境的配置支持。在config目錄下的config.exs文件中可以添加必要的配置項(xiàng),還可以通過(guò)如下語(yǔ)句import不同環(huán)境的配置:

 
 
  1. import_config "#{Mix.env}.exs" 

單元測(cè)試

還有不能忘記的單元測(cè)試,這可是敏捷社區(qū)的隨身法寶啊;Elixir通過(guò)內(nèi)嵌的ExUnit很好地支持了單元測(cè)試的編寫(xiě):

 
 
  1. defmodule MyprojectTest do 
  2.   use ExUnit.Case 
  3.   doctest Myproject 
  4.  
  5.   test "sort ascending orders the correct way" do 
  6.     result = sort_into_ascending_order(fake_created_at_list(["c", "a", "b"])) 
  7.     issues = for issue <- result, do: issue["created_at"] 
  8.     assert issues == ~w{a b c} 
  9.   end 
  10. end 

如此簡(jiǎn)單。要運(yùn)行所有測(cè)試,只需運(yùn)行mix test即可。

其他

Elixir還有很多酷炫的玩意兒,例如Protocol、Behavior,當(dāng)然還有最棒的(當(dāng)然也可能是最令人費(fèi)解的)宏(Macro)。Elixir對(duì)DSL的支持也非常友好,這來(lái)自它繼承的部分Ruby血統(tǒng)。例如,讓我們看看ECTO(一個(gè)基于Elixir開(kāi)發(fā)的支持?jǐn)?shù)據(jù)庫(kù)訪(fǎng)問(wèn)的框架)的一段客戶(hù)代碼:

 
 
  1. defmodule Sample.App do 
  2.   import Ecto.Query 
  3.   alias Sample.Weather 
  4.   alias Sample.Repo 
  5.  
  6.   def keyword_query do 
  7.     query = from w in Weather, 
  8.          where: w.prcp > 0 or is_nil(w.prcp), 
  9.          select: w 
  10.     Repo.all(query) 
  11.   end 
  12.  
  13.   def pipe_query do 
  14.     Weather 
  15.     |> where(city: "Kraków") 
  16.     |> order_by(:temp_lo) 
  17.     |> limit(10) 
  18.     |> Repo.all 
  19.   end 
  20. end 

因?yàn)闆](méi)有大括號(hào)、括號(hào)以及分號(hào)的干擾,代碼可以變得更接近領(lǐng)域邏輯,再加上性感的管道運(yùn)算符,可讀性直接爆表,帥呆了!

【本文為專(zhuān)欄作者“張逸”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】

戳這里,看該作者更多好文


網(wǎng)站欄目:神奇的仙丹,性感的Elixir
本文來(lái)源:http://www.5511xx.com/article/dhojcdc.html