ElixirV1.8新特性
malong 发布于 2021-04-02

Elixir是一种函数式动态语言,用于构建可伸缩、易维护的应用程序。
Elixir是基于Erlang VM的,其广为人知的特点是运行低延时、分布式、可容错的系统,并成功用于Web开发与嵌入式软件领域。
ElixirV1.8在基础设施级别进行了许多改进,改进了编译时间,加快了通用模式的速度,并添加了有关系统内省的特性。

自定义结构检查自定义结构检查

Elixir现在提供了Inspect协议的可派生实现。简而言之,这意味着无论何时检查数据结构,都很容易从中筛选数据。例如,假设您有一个包含安全和隐私敏感信息的用户结构:

defmodule User do
  defstruct [:id, :name, :age, :email, :encrypted_password]
end

默认情况下,如果通过inspect(user)检查用户,它将包括所有字段。这会导致诸如:email和:encrypted_password等字段出现在日志、错误报告等中。您始终可以为此类情况定义Inspect协议的自定义实现,但Elixir v1.8允许您派生Inspect协议,从而使其更简单:

defmodule User do
  @derive {Inspect, only: [:id, :name, :age]}
  defstruct [:id, :name, :age, :email, :encrypted_password]
end

现在将打印所有用户结构,并折叠所有剩余字段:

#User<id: 1, name: "Jane", age: 33, ...>

您还可以传递@derive{Inspect,除了:[…]},以防您希望在默认情况下保留所有字段并仅排除一些字段。

时区数据库支持

在Elixir v1.3中,Elixir添加了四种类型(称为日历类型)来处理日期和时间:Time、Date、DateTime(不带时区)和DateTime(带时区)。在过去的版本中,我们对日历类型添加了许多增强,但是DateTime模块的发展速度总是较慢,因为Elixir没有为时区数据库提供API。
Elixirv1.8现在定义了Calendar.TimeZoneDatabase允许开发人员引入自己的时区数据库。通过定义时区行为的显式约定,Elixir现在可以扩展DateTime API,添加如下函数DateTime.shift_zone/3. 默认情况下,Elixir附带一个名为Calendar.UTCOnlyTimeZoneDatabase只处理UTC。
其他与Calendar相关的改进包括添加Date.day_of_year/1, Date.quarter_of_year/1, Date.year_of_era/1, 和 Date.day_of_era/1..

更快的编译和其他性能改进更快的编译和其他性能改进

由于编译器在去年进行了改进,ElixirV1.8编译代码的速度平均应提高5%。这是另一个版本,我们能够减少编译时间,并为每个人提供更愉快的开发体验。
编译器还为guards中的范围检查(如y..z中的x)、带有插值的charlist(如’foo{bar}baz’)以及通过Record模块处理记录时发出更有效的代码。
最后,EEx模板得到了它们自己的优化,产生了运行速度更快的更紧凑的代码。

改进了$callers的检测和所有权

任务模块是派生轻量级进程以并发执行工作的最常见方法之一。每当您产生一个新进程时,Elixir都会通过$ancestors键来注释该进程的父进程。检测工具可以使用这些信息来跟踪多个进程中发生的事件之间的关系。然而,很多时候,仅仅跟踪$ancestors是不够的。
例如,我们建议开发人员总是在主管的领导下启动任务。这提供了更高的可见性,并允许我们控制在节点关闭时如何终止这些任务。在您的代码中,可以通过调用以下命令来完成:Task.Supervisor.start\子级(我的主管,任务规范)。这意味着,尽管您的代码是调用任务的人,但任务的实际父级将是主管,因为主管是生成它的人。我们会将主管列为任务的$ancestors之一,但您的代码与任务之间的关系已丢失。
在elixirv1.8中,我们现在通过processdictionary中的$callers键跟踪代码和任务之间的关系,该键与现有的$forcens键非常一致。因此,假设任务主管请拨打以上电话,我们有:

[your code] -- calls --> [supervisor] ---- spawns --> [task]

这意味着我们存储以下关系:

[your code]              [supervisor] <-- ancestor -- [task]
     ^                                                  |
     |--------------------- caller ---------------------|

当一个任务直接从您的代码中派生出来时,如果没有主管,那么运行您的代码的进程将同时列在$ancestors和$callers下。
这个小功能非常强大。它允许检测和监视工具更好地跟踪和关联系统中发生的事件。这个特性也可以被“Exto沙盒”之类的工具使用。“exto沙盒”允许开发人员使用事务和所有权机制对数据库并发运行测试,其中每个进程显式地获得分配给它的连接。如果没有$callers,每次生成查询数据库的任务时,该任务都不会知道其调用方,因此无法知道分配给它的连接。这通常意味着不能同时测试依赖于任务的特性。对于$callers,找出这种关系是微不足道的,并且您可以使用计算机的全部功能进行更多的测试。

malong
关注 私信
文章
35
关注
0
粉丝
0