别名( Aliases)
为了便于软件重用,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模块。 当我们使用非常长的模块名称并希望在当前范围中替换那些较短的模块名称时,这非常有用。
NOTE - 别名MUST以大写字母开头。
别名仅在它们被调用的lexical scope内有效。例如,如果文件中有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被定义为macro 。 该宏可用作防护。 这意味着,为了调用Integer.is_odd ,我们需要Integer模块。
使用require Integer函数并运行程序,如下所示。
require Integer
Integer.is_odd(3)
这次程序将运行并生成输出为: true 。
通常,在使用之前不需要模块,除非我们想要使用该模块中可用的宏。 尝试调用未加载的宏将引发错误。 请注意,与alias指令一样, require is also lexically scoped 。 我们将在后面的章节中详细讨论宏。
import
我们使用import指令轻松访问其他模块中的函数或宏,而不使用完全限定名称。 例如,如果我们想多次使用List模块中的duplicate函数,我们可以简单地导入它。
import List, only: [duplicate: 2]
在这种情况下,我们只从List导入函数duplicate(带参数列表长度2)。 虽然:only是可选的,但建议使用它,以避免在命名空间内导入给定模块的所有功能。 :除了函数列表之外,还可以作为选项提供,以便导入模块中的所有内容。
import指令还支持:macros和:only给出的:functions :only 。 例如,要导入所有宏,用户可以写 -
import Integer, only: :macros
请注意,导入也是Lexically scoped ,就像require和alias指令一样。 另请注意, 'import'ing a module also 'require's it 。
use
尽管不是指令,但use是一个与require紧密相关的宏,允许您在当前上下文中使用模块。 开发人员经常使用use宏将外部功能引入当前的词法范围,通常是模块。 让我们通过一个例子来理解use指令 -
defmodule Example do
use Feature, option: :value
end
使用是一个宏,将上述内容转换为 -
defmodule Example do
require Feature
Feature.__using__(option: :value)
end
use Module首先需要模块,然后在Module上调用__using__宏。 Elixir具有出色的元编程功能,它具有在编译时生成代码的宏。 在上面的实例中调用了_ _using__宏,并将代码注入到我们的本地上下文中。 本地上下文是编译时调用use macro的地方。