Elixir学习笔记——别名、需要、导入和使用

2024-06-15 19:04

本文主要是介绍Elixir学习笔记——别名、需要、导入和使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

为了便于软件重用,Elixir 提供了三个指令(alias、require 和 import)以及一个名为 use 的宏,总结如下:

# 为模块添加别名,以便可以将其称为 Bar 而不是 Foo.Bar
alias Foo.Bar, as: Bar

# 需要模块才能使用其宏
require Foo

# 从 Foo 导入函数,以便可以在不带 `Foo.` 前缀的情况下调用它们
import Foo

# 调用 Foo 中定义的自定义代码作为扩展点
use Foo

我们现在将详细探讨它们。请记住,前三个被称为指令,因为它们具有词法范围,而 use 是一个允许使用的模块注入代码的通用扩展点。

别名

alias 允许您为任何给定的模块名称设置别名。

假设一个模块使用 Math.List 中实现的专用列表。alias 指令允许在模块定义中将 Math.List 引用为 List:

原始 List 仍可通过完全限定名称 Elixir.List 在 Stats 中访问。

Elixir 中定义的所有模块都在主 Elixir 命名空间内定义,例如 Elixir.String。但是,为了方便起见,您可以在引用它们时省略“Elixir。”

别名经常用于定义快捷方式。事实上,调用不带 :as 选项的 alias 会自动将别名设置为模块名称的最后一部分,例如:

与以下相同:

请注意,alias 是词法作用域,这允许您在特定函数内设置别名:

在上面的例子中,由于我们在函数 plus/2 内调用 alias,因此别名仅在函数 plus/2 内有效。minus/2 不会受到影响。

需要

Elixir 提供宏作为元编程(编写代码生成代码)的机制。宏在编译时展开。

模块中的公共函数是全局可用的,但为了使用宏,您需要通过要求定义它们的模块来选择加入。

iex>  Integer.is_odd(3)
** (UndefinedFunctionError) function Integer.is_odd/1 is undefined or private. However, there is a macro with the same name and arity. Be sure to require Integer if you intend to invoke this macro
    (elixir) Integer.is_odd(3)
iex>  require Integer
Integer
iex>  Integer.is_odd(3)
true

在 Elixir 中,Integer.is_odd/1 被定义为宏,以便可以将其用作保护。这意味着,为了调用 Integer.is_odd/1,我们需要首先要求 Integer 模块。

请注意,与 alias 指令一样,require 也是词法作用域。我们将在后面的章节中详细讨论宏。

导入

每当我们想从其他模块访问函数或宏而不使用完全限定名称时,我们都会使用 import。请注意,我们只能导入公共函数,因为私有函数永远无法从外部访问。

例如,如果我们想多次使用 List 模块中的 duplicate/2 函数,我们可以导入它:

我们只从 List 导入了函数 duplicate(参数为 2)。虽然 :only 是可选的,但建议使用它,以避免在当前范围内导入给定模块的所有函数。:except 也可以作为选项提供,以便导入模块中除函数列表之外的所有内容。

请注意,import 也是词法范围的。这意味着我们可以在函数定义中导入特定的宏或函数:

在上面的例子中,导入的 List.duplicate/2 仅在该特定函数中可见。duplicate/2 在该模块(或任何其他模块)的任何其他函数中都不可用。

虽然导入对于框架和库构建抽象很有用,但开发人员通常应该更喜欢在自己的代码库中使用别名进行导入,因为别名使被调用函数的来源更清晰。

使用

use 宏经常用作扩展点。这意味着,当您使用模块 FooBar 时,您允许该模块在当前模块中注入任何代码,例如导入自身或其他模块、定义新函数、设置模块状态等。

例如,为了使用 ExUnit 框架编写测试,开发人员应该使用 ExUnit.Case 模块:

在后台,use 需要给定的模块,然后对其调用 __using__/1 回调,允许模块将一些代码注入当前上下文。一些模块(例如,上面的 ExUnit.Case,还有 Supervisor 和 GenServer)使用此机制为您的模块填充一些基本行为,您的模块旨在覆盖或完成这些行为。

一般来说,以下模块:

编译为

由于 use 允许运行任何代码,因此如果不阅读其文档,我们无法真正了解使用模块的副作用。因此,请谨慎使用此功能,并且仅在严格需要时才使用。不要在可以使用导入或别名的地方使用 use。

理解别名

此时,您可能想知道:Elixir 别名到底是什么,它是如何表示的?

Elixir 中的别名是一个大写的标识符(如字符串、关键字等),在编译期间会转换为原子。例如,String 别名默认转换为原子 :"Elixir.String":

通过使用 alias/2 指令,我们可以改变别名扩展为的原子。

别名扩展为原子,因为在 Erlang 虚拟机(以及 Elixir)中,模块始终由原子表示:

这是我们用来调用 Erlang 模块的机制:

模块嵌套

既然我们已经讨论了别名,我们可以讨论嵌套以及它在 Elixir 中的工作原理。请考虑以下示例:

上面的示例将定义两个模块:Foo 和 Foo.Bar。只要它们在同一个词法范围内,第二个模块就可以在 Foo 内作为 Bar 访问。

如果稍后将 Bar 模块移出 Foo 模块定义,则必须通过其全名 (Foo.Bar) 引用它,或者必须使用上面讨论的别名指令设置别名。

注意:在 Elixir 中,您不必在定义 Foo.Bar 模块之前定义 Foo 模块,因为它们实际上是独立的。上面的代码也可以写成:

为嵌套模块添加别名不会将父模块纳入范围。请考虑以下示例:

正如我们将在后面的章节中看到的那样,别名在宏中也起着至关重要的作用,以确保它们是健壮的结构。

多别名/导入/需要/使用

可以同时为多个模块设置别名、导入、要求或使用多个模块。当我们开始嵌套模块时,这尤其有用,这在构建 Elixir 应用程序时非常常见。例如,假设您有一个应用程序,其中所有模块都嵌套在 MyApp 下,您可以同时为模块 MyApp.Foo、MyApp.Bar 和 MyApp.Baz 设置别名,如下所示:

至此,我们完成了对 Elixir 模块的介绍。下一个要介绍的主题是模块属性。

这篇关于Elixir学习笔记——别名、需要、导入和使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1064312

相关文章

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

flask库中sessions.py的使用小结

《flask库中sessions.py的使用小结》在Flask中Session是一种用于在不同请求之间存储用户数据的机制,Session默认是基于客户端Cookie的,但数据会经过加密签名,防止篡改,... 目录1. Flask Session 的基本使用(1) 启用 Session(2) 存储和读取 Se