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

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

系统架构师考点--计算机硬件

大家好。今天我总结一下计算机硬件的一些考点。 一、中央处理单元(CPU) 我们知道,计算机的基本硬件系统由运算器、控制器、存储器、输入设备和输出设备5大部件组成。其中运算器、控制器等部件被集成在一起统称为中央处理单元(Central Proce…

如何在 Windows 上安装 MySQL(保姆级教程2024版)

MySQL 是最流行的数据库管理系统 (DBMS) 之一。它轻量、开源且易于安装和使用,因此对于那些刚开始学习和使用关系数据库的人来说是一个不错的选择。 本文主要系统介绍Windows的环境下MySQL的安装过程和验证过程。 目录 1 安装过程 1.1 前置要求 1.2 下载并安装 …

Linux C编译器从零开发二

自定义分词器 test.c #include <ctype.h> #include <stdarg.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h>typedef enum {TK_PUNCT, // PunctuatorsTK_NUM, // Numeric literalsTK_EOF, // …

手把手带你搞定用户权限控制 | 纯干货

在实际的软件项目开发过程中&#xff0c;用户权限控制可以说是所有运营系统中必不可少的一个重点功能&#xff0c;根据业务的复杂度&#xff0c;设计的时候可深可浅&#xff0c;但无论怎么变化&#xff0c;设计的思路基本都是围绕着用户、角色、菜单这三个部分展开。 如何设计…

RAG工作流在高效信息检索中的应用

介绍 RAG&#xff08;Retrieval Augmented Generation&#xff09;是一种突破知识限制、整合外部数据并增强上下文理解的方法。 由于其高效地整合外部数据而无需持续微调&#xff0c;RAG的受欢迎程度正在飙升。 让我们来探索RAG如何克服LLM的挑战&#xff01; LLM知识限制大…

简单的心电图信号分割方法

代码很简单&#xff0c;很容易看懂。 import pandas as pdimport matplotlib.pyplot as plt #headers [Name, Age, Marks]df pd.read_csv(samples-folder/samples2.csv) dfdf.drop(0)dfdf.drop(1)# print(df) if(len(df.columns) 3): df.columns [sample interval, sig…

自定义注解获取属性对应枚举的翻译值

平时在开发的时候难免会遇到枚举来翻译类&#xff0c;于是写一个自定义注解来在开发的时候自动翻译枚举的值 相关代码如下&#xff1a; Target(ElementType.FIELD) Retention(RetentionPolicy.RUNTIME) Documented JacksonAnnotationsInside public interface EnumShow {/*** …

web错题(1)

action属性是form标签的必须属性&#xff0c;用于指定表单提交时表单数据将被发往哪里 dir能够指定文本显示方向的属性 可以产生下拉列表的标记时<select> multiple属性设为true&#xff0c;表示输入字段可以选择多个值 lable标签的for属性可以把lable绑定到另一个元…

meilisearch,老版本的文档

Elasticsearch 做为老牌搜索引擎&#xff0c;功能基本满足&#xff0c;但复杂&#xff0c;重量级&#xff0c;适合大数据量。 MeiliSearch 设计目标针对数据在 500GB 左右的搜索需求&#xff0c;极快&#xff0c;单文件&#xff0c;超轻量。 所以&#xff0c;对于中小型项目来说…

Unity 之通过自定义协议从浏览器启动本地应用程序

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity 之通过自定义协议从浏览器启动本地应用程序 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进…

PHP框架详解- symfony框架

GPT-4 (OpenAI) Symfony 是一个用 PHP 语言编写的开放源代码的 web 应用框架。Symfony 提供了一组可重用的组件和一个标准化、可扩展的框架&#xff0c;用于构建 web 应用、API、微服务等。它跟其他流行 PHP 框架&#xff08;比如 Laravel&#xff09;一样&#xff0c;旨在加快…

Servlet接口实现

项目搭建 pom文件引入依赖与打包配置。 <dependencies><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId>…

java:spring actuator添加自定义endpoint

# 项目代码资源&#xff1a; 可能还在审核中&#xff0c;请等待。。。 https://download.csdn.net/download/chenhz2284/89437274 # 项目代码 【pom.xml】 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId&…

探索C嘎嘎的奇妙世界:第四关---引用与内联函数

1 引用: 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。 #include<iostream> using namespace std;int main() {int a 0;// 引用&#xff1a;…

分数计算 初级题目

今天继续更题。今天的题目是《第五单元 分数的加减法》初级题目。 定位&#xff1a;题目较为初级&#xff0c;适合预习 参考答案&#xff1a;CACCADACAABACBBCDBCB

Linux文本处理三剑客+正则表达式

Linux文本处理常用的3个命令&#xff0c;脚本或者文本处理任务中会用到。这里做个整理。 三者的功能都是处理文本&#xff0c;但侧重点各不相同&#xff0c;grep更适合单纯的查找或匹配文本&#xff0c;sed更适合编辑匹配到的文本&#xff0c;awk更适合格式化文本&#xff0c;对…

【数据结构】第十六弹---C语言实现希尔排序

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、希尔排序( 缩小增量排序 ) 1.1、预排序实现 1.2、希尔排序代码实现 1.3、代码测试 1.4、时空复杂度分析 1.5、性能比较 总结 上一弹我们…

2024年【四川省安全员C证】考试题及四川省安全员C证考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 四川省安全员C证考试题是安全生产模拟考试一点通总题库中生成的一套四川省安全员C证考试资料&#xff0c;安全生产模拟考试一点通上四川省安全员C证作业手机同步练习。2024年【四川省安全员C证】考试题及四川省安全员…

SUSTAINABILITY,SCIESSCI双检期刊还能投吗?

本期&#xff0c;小编给大家介绍的是一本MDPI出版社旗下SCIE&SSCI双检“毕业神刊”——SUSTAINABILITY。据悉&#xff0c;早在2024年1月&#xff0c;ElSEVIER旗下的Scopus数据库已暂停收录检索期刊SUSTAINABILITY所发表文章&#xff0c;同时重新评估是否继续收录该期刊。随…

Carsim高级开发:VS Connect通讯开发指南

文章目录 前言一、VS Connect 概念引入二、VS Connect 通讯框架三、Carsim 工程配置1、车辆模型配置2、procedure配置3、Run Control配置4、受控车辆名称配置 四、VS Connect Server代码1、打开Sln工程2、代码修改 五、VS Connect Client代码1、函数的调用关系2、carsim_variab…