- Elixir 教程
- Elixir - 首页
- Elixir - 概述
- Elixir - 环境
- Elixir - 基本语法
- Elixir - 数据类型
- Elixir - 变量
- Elixir - 运算符
- Elixir - 模式匹配
- Elixir - 决策
- Elixir - 字符串
- Elixir - 字符列表
- Elixir - 列表和元组
- Elixir - 关键字列表
- Elixir - Map
- Elixir - 模块
- Elixir - 别名
- Elixir - 函数
- Elixir - 递归
- Elixir - 循环
- Elixir - 可枚举
- Elixir - 流
- Elixir - 结构体
- Elixir - 协议
- Elixir - 文件I/O
- Elixir - 进程
- Elixir - 符号
- Elixir - 列表推导
- Elixir - 类型规范
- Elixir - 行为
- Elixir - 错误处理
- Elixir - 宏
- Elixir - 库
- Elixir 有用资源
- Elixir - 快速指南
- Elixir - 有用资源
- Elixir - 讨论
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 module code here
defmodule Bar do
#Bar module code here
end
end
上面给出的示例将定义两个模块:`Foo` 和 `Foo.Bar`。只要它们在相同的词法作用域中,第二个模块可以在 `Foo` 模块内访问为 `Bar`。如果稍后将 `Bar` 模块移到 `Foo` 模块定义之外,则必须使用其全名 (Foo.Bar) 引用它,或者必须使用在别名章节中讨论的 alias 指令设置别名。
注意 - 在 Elixir 中,不需要定义 Foo 模块来定义 Foo.Bar 模块,因为该语言将所有模块名称转换为原子。您可以定义任意嵌套的模块,而无需定义链中的任何模块。例如,您可以定义 `Foo.Bar.Baz` 而无需定义 `Foo` 或 `Foo.Bar`。