Elixir Lang 簡介
已發表: 2015-02-27
Elixir 編程語言簡介(以及我為什麼喜歡它)
幾個月前我寫了一篇文章向你介紹 Golang,以及為什麼我如此喜歡它。 雖然我確實仍然喜歡它,但最近我一直在玩一種新的語言; 長生不老藥。 我買了《Programming Elixir》這本書,並一直在關注它。 我已經開始愛上 Elixir,並希望在本文中向您展示原因。
幾年前我在 Couchbase 工作時,我對 Erlang 和分佈式系統產生了濃厚的興趣。 對我來說,Erlang 令人困惑。 當我看到 Elixir 時,我立即知道我做的是好事。 Elixir 被詳細描述為一種運行在 Erlang VM 之上的函數式並發語言。
我聽過很多次,有人說 Elixir 是 'Ruby for Erlang' 之類的。這個理論並不完全錯誤,但實際上,它主要只是 Elixir 的語法受 Ruby 影響,因為它不共享許多相同的編程結構。 當然,它在方式上與 Erlang 類似,它構建在 Erlang VM 之上,讓我們可以直接訪問原生的 Erlang 原語。
無論如何,毫不猶豫地,讓我們潛入並繼續使用一些 Elixir。
安裝
如果你在 OSX 上運行,安裝就像使用 Homebrew 一樣簡單:
~ brew update
~ brew install erlang
~ brew install elixir
完成此操作後,您應該能夠運行:
~ elixir -v
> Elixir 1.0.2
現在 Elixir 已正確安裝,我們可以打開一個Interactive Elixir並嘗試一些基本的常用類型。
Elixir 的種類
通過輸入啟動交互式 Elixir REPL
> iex
變量:
iex(1)> name = "rbin"
#=> "rbin"
原子:
在 Elixir 中,Atom 是一個常量,它的名字就是它自己的值。
iex(2)> :this_is_an_atom
#=> :this_is_an_atom
iex(3)> :my_atom == :atom
#=> false
元組:
我們使用花括號符號來定義元組。 在 Elixir 中,元組立即存儲在內存中,這意味著獲取元組的大小或訪問元組元素的速度很快,但更新或添加元素的成本很高,因為它需要將整個元組複製到內存中。
iex(4)> tuple = {:hello, "world"}
#=> {:hello, "world"}
iex(5)> elem(tuple, 1)
#=> "world"
列表:
在 Elixir 中,列表作為鍊錶存儲在內存中。 我們可以通過添加元素來簡單地更新列表,但是添加元素的成本更高,因為我們需要遍歷整個列表來計算它的大小。
iex(8)> list = [1, 2, :atom]
#=> [1, 2, :atom]
iex(9)> ["string"] ++ list
#=> ["string", 1, 2, :atom]
iex(10)> list ++ [31]
#=> [1, 2, :atom, 31]
有非常有用的內置函數可用於列表,包括獲取列表的頭部和尾部。
iex(11)> hd(list)
#=> 1
iex(12)> tl(list)
#=> [2, :atom]
匿名函數:
在 Elixir 中,函數是一等公民,這意味著我們可以將函數作為參數傳遞給其他函數。 下面,我們將定義一個名為add的變量,其中包含一個函數,然後我們將把它作為參數傳遞給is_function/1 func 。
iex(14)> add = fn a, b -> a + b end
#Function<12.90072148/2 in :erl_eval.expr/5>
iex(15)> add.(13, 31)
#=> 44
iex(16)> is_function(add)
#=> true
組織我們的項目(混合)
Elixir 附帶了一個名為 Mix 的超級有用的工具。 Mix 是一個構建工具,它使我們能夠非常輕鬆地生成、組織、編譯和測試我們的項目。 它還使我們可以輕鬆管理依賴項。 (總是一個敏感的話題!)要使用 Mix 創建一個新項目,我們只需執行以下操作:
~ mix new myapp --module MyApp
這將創建一個名為myapp的目錄,其中包含一些文件。 它還將在lib/myapp.ex中定義一個模塊MyApp 。
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/myapp.ex
* creating test
* creating test/test_helper.exs
* creating test/myapp_test.exs

Your mix project was created successfully.
You can use mix to compile it, test it, and more:
cd myapp
mix test
如我們所見,我們獲得了基本項目結構所需的所有文件。 我認為這是 Elixir 附帶的更好的功能之一。 擁有項目管理工具非常有用,並且可以節省大量時間。
文件mix.exs是用於配置我們的項目和管理依賴項等的主要文件。我們得到一個test/folder ,我們可以在其中為我們的項目編寫非常類似於 ruby 的測試。 我們當然會得到一個lib/folder ,其中包含我們項目的源文件。 如果我們在我們的應用程序上運行混合測試,我們會得到以下結果:
$ mix test
Compiled lib/myapp.ex
Generated myapp.app
.
Finished in 0.04 seconds (0.04s on load, 0.00s on tests)
1 tests, 0 failures
Randomized with seed 543313
並發
與 Erlang 非常相似,Elixir 使用“Actor”模型進行並發。 我們所有的代碼都在Processes中運行,並且這些進程彼此隔離。 我們可以通過生成進程並在它們之間發送和接收消息來在 Elixir 中創建完全並發的程序。
在 Elixir 中,我們使用spawn函數啟動進程,該函數將另一個函數作為參數。
iex(1)> spawn(fn -> IO.puts 1 + 1 end)
#=> 2
#PID<0.55.0>
如您所見,我們生成了一個輸出 1 + 1 的進程,並且還返回了它的進程 ID。 返回此進程 ID 很有用,因為我們可以將它分配給一個變量,並使用它向進程發送消息。 在我們這樣做之前,我們需要創建一個接收機制來獲取我們發送給進程的消息。 (我們可以在我們的交互式 Elixir會話中逐行執行此操作。)
完成後,我們可以創建一個評估area_loop的進程,並將其分配給pid 。
pid = spawn(fn -> Geometry.area_loop() end)
#=> #PID<0.40.0>
然後我們可以向pid發送我們預定義的代碼將匹配的消息,這取決於它是接收:rectangle原子還是:circle原子。
send pid, {:rectangle, 2, 3}
#=> Area = 6
# {:rectangle,2,3}
send pid, {:circle, 2}
#=> Area = 12.56000000000000049738
# {:circle,2}
我們可以使用Process.alive 查看進程是否仍在運行? 功能。
Process.alive?(pid)
#=> false
結論
我們甚至還沒有在這個博客中觸及表面。 Elixir 中有很多令人驚嘆的功能,希望您繼續親自檢查一下。 我在下面列出了一些學習資源來幫助你,但在你開始深入研究之前,這裡有一些我個人最喜歡的關於 Elixir 的東西:
- 它很容易掌握,具有類似ruby 的語法和類似 Erlang 的原語
- 它背後有一個很棒的社區
- 它的並發模型對我來說既熟悉又非常強大
- 混合是天賜之物,可以節省大量時間
- Elixir 鼓勵我們記錄一切
- 它使構建分佈式應用程序成為一個不那麼混亂的戰場
- 我可以看到 Elixir 有很長的路要走。
資源
在我短暫學習 Elixir 的過程中,我發現一些資源非常有用:
- http://elixir-lang.org/getting-started/introduction.html
- https://pragprog.com/book/elixir/programming-elixir
- https://teamgaslight.com/blog/the-best-resources-for-learning-elixir
- http://exercism.io
*出去喝一口長生不老藥! –@rbin *
