Erlang库

  1. 二进制模块
  2. 格式化文本输出
  3. 加密模块
  4. 图片模块
  5. Erlang长期存储
  6. 数学模块
  7. 队列模块
  8. 随机模块
  9. 压缩模块

Elixir提供了与Erlang库优秀的互用性.事实上,Elixir不鼓励简单地包装Erlang库,而应当使用直接对Erlang代码的接口.本章,我们将给出一些最常用和好用的Elixir中没有的Erlang功能.

当你对Elixir更加熟练时,你会想要探索Erlang的STDLIB参考手册中的细节.

二进制模块

Elixir内置的字符串模块只能处理UTF-8编码的二进制数.而二进制模块能够处理非UTF-8编码的二进制数.

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

上述例子显示了区别,String模块反悔了UTF-8代码点,而:binary处理的是生的数据字节.

格式化文本输出

Elixir不包括与C语言或其它语言中的printf相类似的函数.幸运的是,我们可以使用Erlang标准库中的函数:io.format/2:io_lib.format/2.第一种应对终端输出,第二种适用于io列表.格式说明符与printf的区别,详见Erlang文档.

  1. iex> :io.format("Pi is approximately given by:~10.3f~n", [:math.pi])
  2. Pi is 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> Base.encode16(:crypto.hash(:sha256, "Elixir"))
  2. "3315715A7A3AD57428298676C5AE465DADA38D951BDFAC9348A8A31E9C7401CB"

:crypto模块不是Erlang标准库的一部分,但由Erlang分布式包含.这意味着你必须将:crypto放在你项目的应用列表中,无论是否使用它.你只需修改你的mix.exs文件:

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

图片模块

图片模块(以及图片实用工具)包含了许多用于处理由定点和边组成的有向图的函数.在构造图片之后,其中的算法将有助于寻找例如两个顶点间最短的路径,或图片中的循环.

注意:digraph中的函数会由于边界效应间接地改变图片的结构,同时返回添加了的定点和边.

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

  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}]

Erlang长期存储

模块etsdets分别用于处理内存或硬盘中大量数据结构的存储.

ETS让你创造一个元组的表格.ETS表格默认是受保护的,意味着只有所有者进程能够写入表格,而其它任何进程只能读取.ETS有一些功能可以被当做简单的数据库来使用,键值对存储或缓存机制.

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

队列模块

队列是一种数据结构,它有效地实现了(双头的)FIFO(先进先出)队列:

  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中的函数可用于生成随机数或设置随机种子.

  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模块让你能够在硬盘和内存中读写zip文件,也可以提取文件信息.

下列代码计算了一个zip文件中的文件数量:

  1. iex> :zip.foldl(fn _, _, _, acc -> acc + 1 end, 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."