Elixir入门教程-Erlang的库

  1. binary模块
  2. 格式化文本输出
  3. crypto模块
  4. digraph模块
  5. ETS
  6. math模块
  7. queue模块
  8. rand模块
  9. zip和zlib模块

Elixir提供了非常棒的与Erlang的库交互的能力。实际上,Elixir不鼓励简单地封装Erlang的库,而是提倡直接与Erlang代码交互。本文我们将介绍一些最常见和有用的而在Elixir里找不到的Erlang功能。

当你逐渐熟悉了Elixir,你可能想要探索Erlang的STDLIB指引手册来获得更多细节。

binary模块

Elixir内建的String模块处理用UTF-8编码的二进制数据。当你要处理不一定要用UTF-8编码的二进制数据的时候,binary模块就有用。

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

上面的例子展示了区别;String模块返回Unicode代码点,而 :binary 处理原始数据的字节。

格式化文本输出

Elixir没有包含与C语言和其他语言里的printf函数相似的函数。幸运地是,Erlang标准库函数 :io.format/2 和 :io_lib.format/2 可以被用作这样的功能。第一个函数格式化数据输出到终端,而第二个函数格式化数据为一个iolist。格式化说明符不同于printf,细节请参阅Erlang官方文档

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

另外要注意Erlang的格式化函数需要特别注意Unicode的处理。

crypto模块

crypto模块包含哈希函数、数字签名、加解密等等函数。

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

:crypto模块不是Erlang标准库的一部分,但是它包含在Erlang发行版里。这意味着,任何时候你要使用 :crypto 的时候,就要把它加入你的项目应用列表里。要这么做的话,编辑你的 mix.exs 文件包含它:

1
2
3
def application do
[extra_applications: [:crypto]]
end

digraph模块

digraph模块(还有digraph工具)包含了处理用点和边构建的有向图的函数。在构建了图后,模块里的算法将帮助找到图里的两个节点间的最短路径或回环路径。

给定三个节点,找到从第一个到最后一个节点的最短路径。

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

注意::digraph里的函数在内部修改了图的结构,这是可能的,因为它们被实现为ETS表。下面我们来看看ETS。

ETS

etsdets 模块分别处理内存或硬盘的大数据结构存储。

ETS让你创建一个包含元组的表。默认情况下,ETS表是被保护的,就是说只有拥有者进程可以写这个表,而其他任何进程可以读这个表。ETS有一些功能被用来当做简单数据库、KV存储或者缓存机制。

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

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

math模块

math模块包含常用的数学运算,覆盖三角函数、指数函数、对数函数。

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

queue模块

queue是一个数据结构,它高效地实现了(双端)FIFO(先进先出)队列。

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

rand模块

rand有返回随机数和设置随机种子的函数。

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

zip和zlib模块

zip模块让你从硬盘或内存读写ZIP文件,也提取文件的信息。

下面的代码统计ZIP文件里的文件个数:

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

zlib模块用zlib格式,就如gzip命令里找到的格式,来处理压缩数据:

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

原文链接: http://elixir-lang.org/getting-started/erlang-libraries.html