21-Erlang库

正如前文所言,Elixir是基于Erlang实现的编程语言。
对于Erlang语言库,Elixir提供了完善的交互能力。
而且,实际上,Elixir不只是简单地对Erlang库功能进行语言上的包装(是的,没有Elixir版本的对应Erlang库函数),
而是直接连接Erlang代码(因为同源,Elixir以特定语法来直接调用Erlang库函数)。
本章将展示一些Elixir中没有,但是常用(常见+有用)的Erlang功能函数。

随着对Elixir更加深入的学习和使用,你可能会更多地阅读参考Erlang的
标准库手册

二进制串模块

内建的Elixir字符串模块用来处理UTF-8编码过的二进制串(binaries)。
而Erlang的二进制串模块可能对你更加有用,
因为它可以处理的二进制串不一定非要是UTF-8编码的:

  1. iex>String.to_char_list "Ø"
  2. [216]
  3. iex>:binary.bin_to_list "Ø"
  4. [195,152]

从上面的例子你就能看出一些区别来了;String模块返回UTF-8的字符码,
:binary是原始的数据字节。

Elixir引用Erlang的库函数十分简单。正如这个例子所示,在Erlang库模块名称前面加上冒号,
就可以直接调用Erlang的库函数了。

格式化的字符串输出

Elixir中并没有类似于C中的printf函数。作为一个可选项,你可以使用字符串插值来完成同样的功能:

  1. iex> f =Float.to_string(:math.pi, decimals:3)|>String.rjust(10)
  2. iex> str ="Pi is approximately given by: #{f}"
  3. "Pi is approximately given by: 3.142"

另外,还可以用Erlang标准库中的:io.format/2:io_lib.format/2函数。
第一个格式化后输出到终端,而第二个输出到一个iolist。具体格式化的语法和pringf略有区别,
详见Erlang文档

  1. iex>:io.format("Pi is approximately given by:~10.3f~n",[:math.pi])
  2. Piis approximately given by:3.142
  3. :ok
  4. iex> to_string :io_lib.format("Pi is approximately given by:~10.3f~n",[:math.pi])
  5. "Pi is approximately given by: 3.142\n"

另外需要注意的是Erlang的格式化函数中对Unicode的处理。

日历模块

日历模块 包含本地时间和标准时间的转换函数,
以及其它一些时间函数。

  1. iex>:calendar.day_of_the_week(1980,6,28)
  2. 6
  3. iex>{date, time}=:calendar.now_to_local_time(:erlang.timestamp)
  4. iex> date
  5. {2016,2,17}
  6. iex> time
  7. {22,4,55}

加密模块

加密模块 包含哈希方法,数字签名,
加密等功能函数:

  1. iex>Base.encode16(:crypto.hash(:sha256,"Elixir"))
  2. "3315715A7A3AD57428298676C5AE465DADA38D951BDFAC9348A8A31E9C7401CB"

:crypto 模块不是Erlang的标准库,但是包含在了Erlang发行包中。
这要求你必须在项目的配置文件中列出:crypto模块作为依赖项。
通过修改mix.exs来加载该模块:

  1. def application do
  2. [applications:[:crypto]]
  3. end

有向图模块

有向图模块 (以及
有向图模块工具
包含了处理有向图(有丁点和边构成)的函数。
创建了一个图实例之后,模块的算法即可帮助找寻顶点最短路径、图中的环等。

给出三个顶点,找寻从第一个到最后一个顶点的最短路径:

  1. iex> digraph =:digraph.new()
  2. iex> coords =[{0.0,0.0},{1.0,0.0},{1.0,1.0}]
  3. iex>[v0, v1, v2]=(for c <- coords,do::digraph.add_vertex(digraph, c))
  4. iex>:digraph.add_edge(digraph, v0, v1)
  5. iex>:digraph.add_edge(digraph, v1, v2)
  6. iex>:digraph.get_short_path(digraph, v0, v2)
  7. [{0.0,0.0},{1.0,0.0},{1.0,1.0}]

ETS(Erlang Term Storage):Erlang的“Term存储”机制

模块ets以及
dets
分别处理在内存中、磁盘上存储大型数据结构。

ETS创建一个表来存储元祖。默认情况下,ETS表是受保护的:只有owner进程才能写表,
其它进程只可以读。ETS提供了一些功能,可被当做简单的数据库、键值存储或cache机制使用。

作为副作用,ets模块中的函数会修改表的状态。

  1. iex> table =:ets.new(:ets_test,[])
  2. # Store as tuples with {name, population}
  3. iex>:ets.insert(table,{"China",1_374_000_000})
  4. iex>:ets.insert(table,{"India",1_284_000_000})
  5. iex>:ets.insert(table,{"USA",322_000_000})
  6. iex>:ets.i(table)
  7. <1>{"USA",322000000}
  8. <2>{"China",1_374_000_000}
  9. <3>{"India",1_284_000_000}

数学模块

数学模块 包含了常用数学操作,
如三角函数、指数或底数函数等等。

  1. iex> angle_45_deg =:math.pi()*45.0/180.0
  2. iex>:math.sin(angle_45_deg)
  3. 0.7071067811865475
  4. iex>:math.exp(55.0)
  5. 7.694785265142018e23
  6. iex>:math.log(7.694785265142018e23)
  7. 55.0

队列(queue)模块

队列 queue 是一种数据结构
实现了双向先进先出的高效率队列:

  1. iex> q =:queue.new
  2. iex> q =:queue.in("A", q)
  3. iex> q =:queue.in("B", q)
  4. iex>{value, q}=:queue.out(q)
  5. iex> value
  6. {:value,"A"}
  7. iex>{value, q}=:queue.out(q)
  8. iex> value
  9. {:value,"B"}
  10. iex>{value, q}=:queue.out(q)
  11. iex> value
  12. :empty

随机值(rand)模块

rand模块函数 可以返回随机值或是设置随机seed:

  1. iex>:rand.uniform()
  2. 0.8175669086010815
  3. iex> _ =:rand.seed(:exs1024,{123,123534,345345})
  4. iex>:rand.uniform()
  5. 0.5820506340260994
  6. iex>:rand.uniform(6)
  7. 6

zip和zlib模块

zip模块 可以让你读写磁盘或内存中的zip文件,
以及提取其文件信息等。

以下代码计算了zip压缩包中的文件数量:

  1. iex>:zip.foldl(fn _, _, _, acc -> acc +1end,0,:binary.bin_to_list("file.zip"))
  2. {:ok,633}

zlib模块 处理zlib格式的数据压缩
(如gzip中用的):

  1. iex> song ="
  2. ...> Mary had a little lamb,
  3. ...> His fleece was white as snow,
  4. ...> And everywhere that Mary went,
  5. ...> The lamb was sure to go."
  6. iex> compressed =:zlib.compress(song)
  7. iex> byte_size song
  8. 110
  9. iex> byte_size compressed
  10. 99
  11. iex>:zlib.uncompress(compressed)
  12. "\nMary had a little lamb,\nHis fleece was white as snow,\nAnd everywhere that Mary went,\nThe lamb was sure to go."