Elixir - 别名
为了方便软件重用,Elixir 提供了三个指令 - alias、require 和 import。 它还提供了一个名为 use 的宏,总结如下 −
# 给模块起别名,以便可以将其称为 Bar 而不是 Foo.Bar alias Foo.Bar, as: Bar # 确保模块已编译且可用(通常用于宏) require Foo # 从 Foo 导入函数,这样就可以在没有"Foo."前缀的情况下调用它们 import Foo # 调用 Foo 中定义的自定义代码作为扩展点 use Foo
现在让我们详细了解每个指令。
alias
alias 指令允许您为任何给定的模块名称设置别名。 例如,如果你想给 String 模块起一个别名 'Str',你可以简单地写 −
alias String, as: Str IO.puts(Str.length("Hello"))
上面的程序生成以下结果 −
5
String 模块的别名为 Str。 现在,当我们使用 Str 文字调用任何函数时,它实际上引用了 String 模块。 当我们使用很长的模块名称并希望在当前范围内用较短的模块名称替换它们时,这非常有用。
注意 −别名必须以大写字母开头。
别名仅在调用它们的词法范围内有效。例如, 如果一个文件中有 2 个模块并在其中一个模块中创建了别名,则该别名将无法在第二个模块中访问。
如果您给出内置模块的名称(例如 String 或 Tuple)作为其他模块的别名,访问内置模块,您需要在其前面加上"Elixir."。 例如,
alias List, as: String #现在,当我们使用 String 时,我们实际上是在使用 List。 #使用字符串模块: IO.puts(Elixir.String.length("Hello"))
当上面的程序运行时,会产生以下结果 −
5
require
Elixir 提供宏作为元编程的机制(编写生成代码的代码)。
宏是在编译时执行和扩展的代码块。 这意味着,为了使用宏,我们需要保证其模块和实现在编译期间可用。 这是通过 require 指令完成的。
Integer.is_odd(3)
当上面的程序运行时,会产生如下结果 −
** (CompileError) iex:1: you must require Integer before invoking the macro Integer.is_odd/1
在 Elixir 中,Integer.is_odd 被定义为宏。 该宏可以用作守卫。 这意味着,为了调用 Integer.is_odd,我们需要 Integer 模块。
使用require Integer函数并运行程序,如下所示。
require Integer Integer.is_odd(3)
这次程序将运行并产生输出:true。
一般来说,在使用之前不需要模块,除非我们想使用该模块中可用的宏。 尝试调用未加载的宏将引发错误。 请注意,与别名指令一样,require 也具有词法作用域。 我们将在后面的章节中详细讨论宏。
import
我们使用 import 指令轻松访问其他模块中的函数或宏,而无需使用完全限定名称。 例如,如果我们想多次使用 List 模块中的 duplicate 函数,我们只需导入它即可。
import List, only: [duplicate: 2]
在本例中,我们仅从 List 导入函数重复(参数列表长度为 2)。 尽管 :only 是可选的,但建议使用它,以避免导入命名空间内给定模块的所有函数。 : except 也可以作为选项给出,以便导入模块中除函数列表之外的所有内容。
import 指令还支持将 :macros 和 :functions 赋予 :only。 例如,要导入所有宏,用户可以编写 −
import Integer, only: :macros
请注意,导入也具有词法范围,就像 require 和 alias 指令一样。 另请注意,"import"模块也"需要它"。
use
尽管不是指令,use 是一个与 require 紧密相关的宏,它允许您在当前上下文中使用模块。 开发人员经常使用 use 宏将外部功能引入当前词法范围(通常是模块)。 让我们通过一个例子来理解 use 指令 −
defmodule Example do use Feature, option: :value end
use 是一个宏,将上面的内容转换为 −
defmodule Example do require Feature Feature.__using__(option: :value) end
use Module 首先需要该模块,然后调用 Module 上的 __using__ 宏。 Elixir 具有强大的元编程功能,并且具有在编译时生成代码的宏。 在上面的实例中调用了 __using__ 宏,并将代码注入到我们的本地上下文中。 本地上下文是编译时调用 use 宏的地方。