Erlang库

Elixir与Erlang库提供了出色的互操作性。事实上,Elixir不鼓励直接与Erlang代码进行接口封装Erlang库。在本节中,我们将介绍一些在Elixir中未找到的最常见和有用的Erlang功能。

随着您对Elixir更加精通,您可能需要更详细地了解Erlang STDLIB参考手册

二进制模块

内置的Elixir字符串模块处理以UTF-8编码的二进制文件。当您处理不一定是UTF-8编码的二进制数据时,二进制模块很有用。

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

上面的例子显示了差异; 该String模块返回Unicode代码点,同时:binary处理原始数据字节。

格式化文本输出

Elixir不包含类似于printfC和其他语言中的函数。幸运的是,Erlang的标准库函数:io.format/2:io_lib.format/2可被使用。第一种格式为终端输出,第二种格式为iolist。格式说明符与之不同printf详细信息请参考Erlang文档

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处理。

加密模块

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

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

:crypto模块不是Erlang标准库的一部分,但包含在Erlang发行版中。这意味着:crypto无论何时使用它,您都必须列出项目的应用程序列表。要做到这一点,编辑你的mix.exs文件包括:

def application do
  [extra_applications: [:crypto]]
end

有向图模块

digraph模块(以及digraph_utils)包含用于处理由顶点和边构成的有向图的函数。在构建图之后,那里的算法将有助于找到例如两个顶点之间的最短路径或图中的循环。

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

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表实现的,下面会解释。

Erlang Term Storage

这些模块etsdets手柄存储在存储器中或分别在磁盘上大量数据结构。

ETS让你创建一个包含元组的表格。默认情况下,ETS表是受保护的,这意味着只有所有者进程可以写入表,但任何其他进程都可以读取。ETS有一些功能可用作简单数据库,键值存储或缓存机制。

ets模块中的功能将修改表的状态作为副作用。

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模块包含常用的数学运算,涵盖三角函数,指数函数和对数函数。

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是一种有效实现(双端)FIFO(先进先出)队列的数据结构

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具有返回随机值和设置随机种子的功能。

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文件中的文件数量:

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

zlib模块处理zlib格式的数据压缩,如gzip命令中所示。

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."