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 模块的介绍。下一个要介绍的主题是模块属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/711429.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024 年最新使用 Node 搭建QQ开放平台官方 QQ 频道机器人详细教程(更新中)

注册 QQ 开放平台账号 QQ 开放平台是腾讯应用综合开放类平台,包含 QQ 机器人、QQ 小程序、QQ 小游戏 等集成化管理,也就是说你注册了QQ 开放平台,你开发 QQ 机器人还是 QQ 小程序都是在这个平台进行部署上线和管理。 如何注册 QQ 开放平台账…

Internet Download Manager ( 极速下载器 ) 序列号注册码 IDM下载器注册机中文激活破解版

IDM下载器(Internet Download Manager)是一款专业的下载管理软件,它通过多线程技术和智能文件分段技术,有效提升下载速度,并支持断点续传,还具有计划下载功能,用户可以设置特定的下载时间,非常适合需要在特…

C#批量设置海康和大华录像机NVR,GB28181的通道编码.

我经常要把小区海康或者大华的硬盘录像机推送到自己搭建的gb28181监控平台,每次几百个摄像头编码,有点头大,就用了1个多周写了个批量设置海康和大华硬盘录像机的通道编码的程序,海康和大华的SDK简直不是人看的. 太乱了. 大华读取通道编码的代码 /// <summary>/// 获取通道…

虚拟机上安装centos7

目录 1&#xff0c;下载centos镜像2&#xff0c;在VMware中新建虚拟机3&#xff0c;为新创建的虚拟机挂载镜像4&#xff0c;安装centos75&#xff0c;配置网络 1&#xff0c;下载centos镜像 直接下载地址 https://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.8.2003/isos/x8…

干部选拔任用的六条原则

在干部选拔任用的过程中&#xff0c;为确保选拔出的干部能够真正符合党和人民的期望&#xff0c;必须遵循以下六条原则&#xff1a; 一、党管干部原则 党管干部原则是指在整个干部选拔任用过程中&#xff0c;党要发挥总揽全局、协调各方的领导作用&#xff0c;确保选拔出的干…

[渗透测试学习] Runner-HackTheBox

Runner-HackTheBox 信息搜集 nmap扫描端口 nmap -sV -v 10.10.11.13扫描结果如下 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0) 80/tcp open http nginx 1.18.0 (Ubuntu) 8000…

Echarts图表:地图都有哪些配置项,一文告诉你

地图是可视化大屏中最常见的组件&#xff0c;echart图表中关于地图的组件非常多&#xff0c;那么该如何进行配置&#xff0c;让地图和自己的设计稿保持一致。贝格前端工场为大家列举一下。 charts地图图表在配置项中有以下常用的配置选项&#xff1a; title&#xff1a;图表标…

TCP协议报头详解

目录 前言 TCP特点 TCP报头 1.源端口和目的端口 2.序号 3.确认号 4.数据偏移 5.保留 6.控制位 ① 紧急URG&#xff08;URGent&#xff09; ② 确认ACK&#xff08;ACKnowledgment&#xff09; ③ 推送PSH&#xff08;PuSH&#xff09; ④复位RST&#xff08;ReSeT&…

【二】【动态规划NEW】91. 解码方法,62. 不同路径,63. 不同路径 II

91. 解码方法 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; ‘A’ -> “1” ‘B’ -> “2” … ‘Z’ -> “26” 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可能有多种方法&#xff…

AI Vs 作家?Groqbook: AI写书神器,使用 Groq 和 Llama3 几秒生成一本完整的书籍!

✨点击这里✨&#xff1a;&#x1f680;原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; AI Vs 作家&#xff1f;Groqbook: AI写书神器&#xff0c;使用 Groq 和 Llama3 几秒生成一本完整的…

awtk如何实现键盘和输入框

1.创建默认键盘 新建窗体-keyboard 2.新建编辑框 3.设置编辑框属性 4.点击编辑框即可打开默认键盘&#xff0c;若想修改键盘样式可以在默认键盘修改或自定义键盘 5.获取输入字符 widget_t* wifi_edit widget_lookup(win, "edit", TRUE);//获取单行编辑控件 widge…

python简单练习案例-石头剪刀布小游戏

&#x1f308;所属专栏&#xff1a;【python】 ✨作者主页&#xff1a; Mr.Zwq ✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01;…

在 Windows 环境下安装mysql步骤(MySQL)

文章目录 一、下载 MySQL二、解压安装包到磁盘三、配置环境&#xff08;管理员权限&#xff09;四、安装 MySQL&#xff08;管理员权限&#xff09; 一、下载 MySQL 如下图&#xff1a;为你的电脑下载对应操作系统的 MySQL 安装包 二、解压安装包到磁盘 三、配置环境&#x…

sprintboot容器功能

容器 容器功能Spring注入组件的注解Component&#xff0c;Controller&#xff0c;Service&#xff0c;Repository案例演示 Configuration应用实例传统方式使用Configuration 注意事项和细节 Import应用实例 ConditionalConditional介绍应用实例 ImportResource应用实例 配置绑定…

金融科技:推动保险行业数字化转型的引擎

随着科技的飞速发展&#xff0c;金融科技&#xff08;FinTech&#xff09;已经成为推动金融行业变革的重要力量。特别是在保险行业&#xff0c;金融科技正引领着一场深刻的数字化转型&#xff0c;为保险公司带来了前所未有的机遇与挑战。本文将探讨金融科技如何推动保险行业的数…

redis设计与实现(五)RDB与AOF持久化

RDB持久化 因为Redis是内存数据库&#xff0c;它将自己的数据库状态储存在内存里面&#xff0c;所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面&#xff0c;那么一旦服务器进程退出&#xff0c;服务器中的数据库状态也会消失不见。 为了解决这个问题&#xff0c;…

Go TOKEN机制与跨域处理方式

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

java学习 项目篇 一

学习地址&#xff1a;https://www.bilibili.com/video/BV1TP411v7v6?p6&spm_id_frompageDriver&vd_sourcea6f7db332f104aff6fadf5b3542e5875 后端环境搭建 Entity 实体&#xff0c;通常和数据库的表对应DTO 数据传输对象&#xff0c;用于程序中各层之间传递数据 (前端…

Windows安装配置CUDA12.5

搞大模型往往都需要GPU加速&#xff0c;本次在家里的PC上安装CUDA来实现GPU加速。 一、环境准备 操作系统&#xff1a;Windows11 23H2 GPU&#xff1a;RTX 4070 Ti Super 显卡驱动&#xff1a;555.99 &#xff08;NVIDIA GeForce 驱动程序 - N 卡驱动 | NVIDIA&#xff09; …

LaDM3IL:多实例学习用于免疫库分类

一个人的免疫组库由某一时间点的大量适应性免疫受体组成&#xff0c;代表了该个体的适应性免疫状态。免疫组库分类和相关受体识别有可能为新型疫苗的开发做出贡献。大量的实例对免疫组库分类提出了挑战&#xff0c;这可以表述为大规模多实例学习 (MMIL&#xff0c;Massive Mult…