Elixir - 别名



为了方便软件重用,Elixir 提供了三个指令 - **alias、require** 和 **import**。它还提供了一个名为 use 的宏,总结如下:

# Alias the module so it can be called as Bar instead of Foo.Bar
alias Foo.Bar, as: Bar

# Ensure the module is compiled and available (usually for macros)
require Foo

# Import functions from Foo so they can be called without the `Foo.` prefix
import Foo

# Invokes the custom code defined in Foo as an extension point
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
#Now when we use String we are actually using List.
#To use the string module: 
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**。

通常,模块在使用前不需要加载,除非我们想使用该模块中可用的宏。尝试调用未加载的宏将引发错误。请注意,与 alias 指令一样,require 也具有词法作用域。我们将在后面的章节中详细讨论宏。

import

我们使用 **import** 指令轻松访问其他模块中的函数或宏,而无需使用完全限定的名称。例如,如果我们想多次使用 List 模块中的 **duplicate** 函数,我们可以简单地导入它。

import List, only: [duplicate: 2]

在这种情况下,我们只从 List 中导入函数 duplicate(带参数列表长度为 2)。虽然 **:only** 是可选的,但建议使用它以避免将给定模块的所有函数导入命名空间。也可以使用 **:except** 作为选项,以导入模块中的所有内容,除了函数列表之外。

**import** 指令还支持将 **:macros** 和 **:functions** 传递给 **:only**。例如,要导入所有宏,用户可以编写:

import Integer, only: :macros

请注意,import 也像 require 和 alias 指令一样具有**词法作用域**。还要注意,**'导入' 模块也 '需要' 它**。

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 宏的地方。

广告