[Erlang 0108] Elixir 入門


   Erlang Resources里面關於Elixir的資料越來越多,加上Joe Armstrong的這篇文章,對Elixir的興趣也越來越濃厚,投入零散時間學習了一下.零零散散,測試代碼寫了一些,Evernote中筆記更是混亂,還是逐步整理出來.

   Elixir is a functional, meta-programming aware language built on top of the Erlang VM. It is a dynamic language with flexible syntax and macro support that leverages Erlang's abilities to build concurrent, distributed and fault-tolerant applications with hot code upgrades.

 

Git首頁 https://github.com/elixir-lang/elixir
Elixir官網 http://elixir-lang.org/

 

各種環境安裝Elixir

需要Erlang R16B或更新版本,安裝Elixir參考下面的列表.之前有人問是否可以在windows中使用Elixir,下面列表中包含了Chocolatey安裝的方案:

Homebrew for Mac OS X

 Update your homebrew to latest with brew update
 Install Elixir: brew install elixir

Fedora 17+ and Fedora Rawhide

 sudo yum -y install elixir

Arch Linux (on AUR)

 yaourt -S elixir

openSUSE (and SLES 11 SP3+)

 Add Erlang devel repo with zypper ar -f obs://devel:languages:erlang/ erlang
 Install Elixir: zypper in elixir

 Gentoo

 emerge --ask dev-lang/elixir

 Chocolatey for Windows

 cinst elixir

 

源碼編譯

如果是從Git獲取源代碼編譯使用

$ git clone https://github.com/elixir-lang/elixir.git
$ cd elixir
$ make test

 

 

好吧,Windows

 雖然不建議在Windows中搞Erlang相關的東西,但考慮到還是有很多小伙伴習慣在Windows中做開發,還是嘗試一下在Windows環境中安裝Elixir.我們使用的工具是Chocolatey,它依附於Windows PowerShell的軟件庫工具,官網有一鍵安裝的批處理命令.安裝Chocolatey之后,直接執行cinst elixir即可完成elixir及其依賴庫的安裝以及環境變量的配置,安裝目錄在C:\tools\Elixir ,不過進入bin目錄執行腳本會閃退,把錯誤重定向出來如下

c:\tools\Elixir\bin>iex
'ETLOCAL' is not recognized as an internal or external command,
operable program or batch file.
'et' is not recognized as an internal or external command,
operable program or batch file.
'or' is not recognized as an internal or external command,
operable program or batch file.
'f' is not recognized as an internal or external command,
operable program or batch file.
Usage: elixir.bat [options] [.exs file] [data]
'cho.' is not recognized as an internal or external command,

 

   這是因為腳本解析錯誤,解決方法很簡單:打開elixir.bat腳本用正則在每行的頭添加個空格即可.修改后運行:

Interactive Elixir (0.10.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

 

我后續的測試都將在Centos中完成,不再考慮Windows環境的情況.

 

開發環境

還用說,Sublime Text通過Package Control安裝Elixir插件即可,看截圖

 

iex


 在Erlang學習過程中有一個強大的REPL工具EShell,絕大部分的測試和調試都可以在EShell中完成.Elixir同樣提供了一個這樣的工具iex,而且更為強大(比如可以在Shell中可以定義module).

熟悉一下iex,h()可以看到一些快捷的方法,比如查看一個方法的文檔,清屏什么的,看下面的例子

iex(5)> h()
# IEx.Helpers

Welcome to Interactive Elixir. You are currently
seeing the documentation for the module `IEx.Helpers`
which provides many helpers to make Elixir's shell
more joyful to work with.

This message was triggered by invoking the helper
`h()`, usually referred to as `h/0` (since it expects 0
arguments).

There are many other helpers available:

* `c/2` — compiles a file at the given path
* `cd/1` — changes the current directory
* `clear/0` — clears the screen
* `flush/0` — flushes all messages sent to the shell
* `h/0` — prints this help message
* `h/1` — prints help for the given module, function or macro
* `l/1` — loads the given module's beam code and purges the current version
* `ls/0` — lists the contents of the current directory
* `ls/1` — lists the contents of the specified directory
* `m/0` — prints loaded modules
* `pwd/0` — prints the current working directory
* `r/0` — recompile and reload all modules that were previously reloaded
* `r/1` — recompiles and reloads the given module's source file
* `s/1` — prints spec information
* `t/1` — prints type information
* `v/0` — prints the history of commands evaluated in the session
* `v/1` — retrieves the nth value from the history
* `import_file/1`
— evaluates the given file in the shell's context

Help for functions in this module can be consulted
directly from the command line, as an example, try:

h(c/2)

You can also retrieve the documentation for any module
or function. Try these:

h(Enum)
h(Enum.reverse/1)

To learn more about IEx as a whole, just type `h(IEx)`.
iex(6)> h(size)
* def size(arg)

Returns the size of the given argument, which must be a tuple
or a binary. If possible, please use `tuple_size` or `byte_size`.

iex(7)> h(length)
* def length(list)

Returns the length of `list`.

Allowed in guard tests.

## Examples

iex> length([1, 2, 3, 4, 5, 6, 7, 8, 9])
9

iex(8)>

 如何退出iex? Ctrl+c 然后 a  

基本數據類型

iex> 1 # integer
iex> 0x1F # integer
iex> 1.0 # float
iex> :atom # atom / symbol
iex> {1,2,3} # tuple
iex> [1,2,3] # list
iex> <<1,2,3>> # bitstring

 

注意上面:atom這種風格和Ruby是一致的,且在Ruby中這種數據類型就是 symbol.作為一種為了取悅開發者而生的開發語言,Ruby提供了很多讓開發者爽到的便利,Elixir從Ruby偷師不少,后續討論中可以看到.

iex(22)> 0x1F
31
iex(23)> 
iex(24)> size {1,2,3}
3
iex(25)> length [12,34,56,66]
4

 

字符串!字符串!

先看一個取長度的測試:

iex(11)> length("hello")
** (ArgumentError) argument error
:erlang.length("hello")
erl_eval.erl:569: :erl_eval.do_apply/6
src/elixir.erl:138: :elixir.eval_forms/3

iex(11)> size("hello") 
5
iex(12)>

 

細心的你一定發現了上面列舉基本數據類型的時候沒有提到string.上面用到了length和size,兩者的區別是什么?length適用於需要遍歷計算才能得到長度的場景,Size用於長度已經預計算的情況.換句話說,"hello"是長度是預計算出來的,沒有遍歷,換句話說,"hello"在Erlang中是list在Elixir中不是!那string到底是什么呢?Elixir還有單引號形式的字符串,這兩種又有什么區別?抓狂了吧,其實string只不過是一堆排列在一起的字節而已,而二進制數據只不過是一串數據位而已.看測試:

iex(48)> is_binary('zen')
false
iex(49)> is_list('zen') 
true
iex(50)>
nil
iex(51)> is_binary("zen")
true
iex(52)> is_list("zen") 
false
iex(53)> <<"zen">> == "zen"
true
iex(54)> <<'zen'>> == "zen"
true
iex(55)> <<'zen'>> == 'zen'
false
iex(56)> <<122,101,110>> == "zen"
true

 

深究一下size和length,我們打開elixir-master\lib\elixir\lib \kernel.ex文件,可以找到下面的代碼

@doc """
  Returns the size of the given argument, which must be a tuple
  or a binary. If possible, please use `tuple_size` or `byte_size`.
  """
  @spec size(tuple|binary) :: non_neg_integer
  def size(arg) do
    :erlang.size(arg)
  end

  @doc """
  Returns the length of `list`.

  Allowed in guard tests.

  ## Examples

      iex> length([1, 2, 3, 4, 5, 6, 7, 8, 9])
      9
  """
  @spec length(list) :: non_neg_integer
  def length(list) do
    :erlang.length(list)
  end

 

 

在Elixir中雙引號和單引號表示的字符串是不同的,看上面的例子, "zen", <<"zen">>,<<'zen'>>都是 <<122,101,110>>數據的語法糖;而'zen'本質上是char list,看下面的代碼:

iex(59)> [122,101,110] == "zen" 
false
iex(60)> [122,101,110] == 'zen'
true
iex(61)>

 

提到string就不可避免提到對unicode的支持,Elixir的基礎是Erlang R16B01,所以支持unicode不費力,我們先從一
在Erlang中取ASCII的快捷運算符 $a 在Elixir中使用的是"?",不過這個是增強版的,它可以字符的Codepoint

iex(29)> ?a
97
iex(30)> [?a,?b,?c]
'abc'
iex(31)> [?a,?b,?c,1]
[97, 98, 99, 1]
iex(53)> ?24320
iex(54)> ?24515

iex(51)> String.codepoints "a我b們c開心"
["a", "", "b", "", "c", "", ""]

iex(59)> <<content::utf8,restcontent::binary >>="我們很開心abc"
"我們很開心abc"
iex(60)> content
25105
iex(61)> ?25105
iex(62)> restcontent
"們很開心abc"


iex(43)> is_bitstring("hello開心")
true
iex(44)> bit_size("hello開心") 
88
iex(45)> bit_size("開心") 
48
iex(47)> size("wo們")
5

 

之前我們分析過Erlang字符串截斷的例子,里面提到了"開心"這兩個漢字都是三字節模板,所以這里的bit_size是48,"wo們"是兩個單字節加上一個三字節所以是5.

繼續看Elixir字符串處理還有哪些特色:

字符串連接:

iex(74)> "foo" <> "bar"
"foobar"

 

字符串占位符:

iex(37)> name="zen"
"zen"
iex(38)> "hello,I am #{name}"
"hello,I am zen"
iex(39)>

 

Ruby里面把上面占位替換成為表達式替換"Expression Substitution",看Ruby的例子

x, y, z = 12, 36, 72
puts "The value of x is #{ x }.
puts "The sum of x and y is #{ x + y }.
puts "The average was #{ (x + y + z)/3 }."

 

更多字符串操作 http://elixir-lang.org/docs/stable/String.html

 

先到這里,小圖一張 小黃人 最近它們很火:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM