Elixir - 模块

在 Elixir 中,我们将多个功能分组为模块。 我们在前面的章节中已经使用过不同的模块,例如 String 模块、Bitwise 模块、Tuple 模块等。

为了在 Elixir 中创建我们自己的模块,我们使用 defmodule 宏。 我们使用 def 宏来定义该模块中的函数 −

defmodule Math do
   def sum(a, b) do
      a + b
   end
end

在下面的部分中,我们的示例将变得更长,并且在 shell 中将它们全部键入可能会很棘手。 我们需要学习如何编译 Elixir 代码以及如何运行 Elixir 脚本。

编译

将模块写入文件总是很方便,这样它们就可以被编译和重用。 假设我们有一个名为 math.ex 的文件,其中包含以下内容 −

defmodule Math do
   def sum(a, b) do
      a + b
   end
end

我们可以使用命令编译文件 −elixirc :

$ elixirc math.ex

这将生成一个名为 Elixir.Math.beam 的文件,其中包含已定义模块的字节码。 如果我们再次启动 iex,我们的模块定义将可用(前提是 iex 在字节码文件所在的同一目录中启动)。 例如,

IO.puts(Math.sum(1, 2))

上面的程序将生成以下结果 −

3

脚本模式

除了 Elixir 文件扩展名 .ex 之外,Elixir 还支持 .exs 文件进行脚本编写。 Elixir 以完全相同的方式处理这两个文件,唯一的区别在于目标。 .ex 文件用于编译,而 .exs 文件用于脚本编写。 执行时,两个扩展都会编译并将其模块加载到内存中,尽管只有 .ex 文件以 .beam 文件的格式将其字节码写入磁盘。

例如,如果我们想在同一个文件中运行Math.sum,我们可以通过以下方式使用.exs −

Math.exs

defmodule Math do
   def sum(a, b) do
      a + b
   end
end
IO.puts(Math.sum(1, 2))

我们可以使用 Elixir 命令运行它 −

$ elixir math.exs

上面的程序将生成以下结果 −

3

该文件将在内存中编译并执行,并打印"3"作为结果。 不会创建任何字节码文件。

模块嵌套

模块可以嵌套在 Elixir 中。 该语言的这一特性可以帮助我们以更好的方式组织代码。 要创建嵌套模块,我们使用以下语法 −

defmodule Foo do
   #Foo模块代码在这里
   defmodule Bar do
      #Bar模块代码在这里
   end
end

上面给出的示例将定义两个模块:FooFoo.Bar。 第二个可以作为 Foo 内的 Bar 进行访问,只要它们位于相同的词法范围内。 如果稍后将 Bar 模块移到 Foo 模块定义之外,则必须通过其全名 (Foo.Bar) 引用它,或者必须使用别名章节中讨论的别名指令设置别名。

注意 − 在 Elixir 中,不需要为了定义 Foo.Bar 模块而定义 Foo 模块,因为该语言将所有模块名称翻译为原子。 您可以定义任意嵌套的模块,而无需在链中定义任何模块。 例如,您可以定义 Foo.Bar.Baz,而不定义 FooFoo.Bar