灵丹妙药1.11

2020-10-07 12:11:36

在最近的版本中,Elixir团队一直专注于编译器,无论是在编译时捕获更多错误,还是在提高速度方面都是如此。ELEXIRV1.11在这两个方面都取得了很好的进展。此版本还包括许多其他优点,例如更紧密的Erlang集成、对更多保护表达式的支持、内置日期时间格式设置和其他日历增强。

在此期间,我们还开始在我们的网站上发布一系列生产案例,介绍Elixir在Brex、Farmbot和Heroku的使用情况,很快还会有更多的案例。

在v1.10的基础上,我们进一步集成了Erlang的新日志记录器,添加了四个新的日志级别:通知、严重、警报和紧急,与syslog标准中的所有日志级别相匹配。Logger模块现在通过将映射和关键字列表传递给其各种功能来支持结构化日志记录。还可以通过Logger.put_module_level/2函数指定每个模块的日志级别。未来版本中将添加每个应用程序的日志级别。

IEX也得到了改进,可以直接从您的Elixir终端显示Erlang模块的文档。例如,下面是我访问Erlang的gen_server模块的文档的片段:

这可以与Erlang/OTP23+一起使用,并且要求已经使用文档块编译了Erlang模块。非常感谢Erlang/OTP团队和Erlang生态系统基金会的文档工作组使这成为可能。

Elixir v1.11构建在最近添加的编译跟踪程序之上,以跟踪应用程序边界。从本版本开始,如果您从现有模块调用函数,但此模块不属于您列出的任何依赖项,则Elixir将发出警告。

这两个条件看起来可能是矛盾的。毕竟,如果模块可用,那么它一定来自依赖项。在两种情况下并非如此:

Elixir和Erlang/OTP中的模块始终可用-即使它们的应用程序未明确列为依赖项

在伞形项目中,因为所有子应用程序都是在同一个VM内编译的,所以即使您不依赖于所述兄弟项目,也可能有来自兄弟项目的模块可用。

这个新的编译器检查确保您调用的所有模块都作为依赖项的一部分列出,否则会发出如下警告:

:ssl.connect/2在application:ssl中定义,当前应用程序使用,但当前应用程序不直接依赖:ssl。要解决此问题,您必须执行以下操作之一:1.如果:SSL是Erlang/Elixir的一部分,则必须将其包含在您的Mix.exs 2中的:Extra_Applications Inside";def application";下。如果:SSL是一个依赖项,请确保它列在Mix.exs中的";def deps";下面。如果您不想向:SSL添加要求,您可以选择通过将[xref:[Exclude::SSL]添加到您的&34;def项目中来跳过此警告。

这在伞形项目中带来了额外的好处,因为它要求子应用程序显式列出它们的依赖项,完全拒绝兄弟项之间的循环依赖项。

在Elixirv1.11中,编译器还跨函数体跟踪结构和映射字段。例如,假设您想要编写以下代码:

如果:age字段有拼写错误或:age字段尚未定义,编译器将相应失败。但是,如果您编写了以下代码:

编译器不会捕获缺少的字段,并且只会在运行时引发错误。在1.11版中,Elixir将跟踪同一函数中所有map和struct字段的使用情况,并在上述情况下发出警告:

警告:表达式:#example.exs:7user.age`中未定义的字段`age`需要以下字段之一:name,address,where";user";在:#example.exs:7%user{}=userExample.exs:7:Check.drive?/1中被赋予类型%user{}=userConflict

编译器还检查二进制构造函数。考虑到您必须使用基于长度的编码通过线路发送字符串,其中字符串的前缀是其长度,最高可达4MBs。您的初始尝试可能如下所示:

但是,上面的代码有一个错误。除非另有说明,否则在<;<;>;>;之间给出的每个段必须是整数。对于Elixir v1.11,编译器会告诉您:

警告:不兼容的类型:表达式中的<;<;byte_size(string)::integer()-size(32),()!~INTEGER(),其中";String";在:#foo.exs:4<;<;byte_size(string)::integer()-size(32),String>;>;WHERE";String";中被赋予类型INTEGER()。在:#foo.exs:3IS_BINARY(字符串)中被赋予类型BINARY()提示:除非另有说明,否则假定给予二进制文件的所有表达式都是INTEGER()类型。例如,<;<;expr&>;>;假定";expr&34;是整数。传递修饰符,如<;<;expr::Float>;>;或<;<;expr::Binary>;>;以更改默认行为。foo.exs:4:Check.run_length/1处发现的冲突。

虽然其中一些警告可以由编译器自动修复,但未来的版本也将跨函数执行这些检查,并可能跨模块执行这些检查,在这些情况下,不需要(也不可能)自动修复。

Elixir v1.11对编译器跟踪文件依赖关系的方式进行了许多改进,这样,接触一个文件会导致重新编译的文件更少。在以前的版本中,Elixir跟踪三种类型的依赖关系:

编译时依赖关系-如果A在编译时(如使用宏)依赖于B,则每当B更改时,都会重新编译A。

结构依赖关系-如果A依赖于B的结构,则每当B的结构定义更改时,都会重新编译A。

但是,因为依赖关系是可传递的,所以如果A在编译时依赖于B,而B在运行时依赖于C,那么A将在编译时依赖于C。因此,减少编译时依赖项的数量非常重要。

Config/runtime.exs与Elixir中的任何其他配置文件的工作方式相同。但是,由于config/runtime.exs要在生产系统中运行,在生产系统中我们的Mix构建工具不可用,因此开发人员不能在config/runtime.exs中使用Mix.env()或Mix.target()。相反,它们必须使用已添加到Config模块的新config_env()和config_target()。

虽然将继续支持config/release ases.exs,但开发人员可以迁移到config/runtime.exs,而不会丢失功能。例如,如下所示的config/release ases.exs文件。

可以作为config/runtime.exs按原样运行。但是,鉴于config/runtime.exs在所有环境中运行,您可能希望将部分配置限制为:Prod环境:

如果这两个文件都可用,版本将选择现在首选的config/runtime.exs,而不是config/release ases.exs。

总而言之,Mix还包括一个名为Mix app.config的新任务。此任务加载所有应用程序并对其进行配置,而不启动它们。每当您编写自己的混合任务时,通常都希望在运行自己的代码之前调用Mix app.start或Mix app.config。哪一个更好取决于您是要运行应用程序还是只希望配置应用程序。

ELIXIRV1.11添加了IS_STRUCT/2、IS_EXCEPTION/1和IS_EXCEPTION/2保护。它还在卫士中添加了对map.field语法的支持。

Calendar模块附带一个新的Calendar.strftime/3函数,该函数提供基于strftime格式的日期时间格式。日期模块获得了用于处理周和月的新函数,如Date.start_of_Month/1和Date.end_of_Week/2。最后,所有日历类型都具有与格里高利时间戳相互转换的函数,如Date.from_Gregorian_Days/2和NaveDateTime.to_Gregorian_Second/1。

最后,为了使前面小节中描述的编译器跟踪改进更具可见性,我们还添加了混合外部参照的新功能。混合外部参照是一项描述项目中文件之间的交叉引用的任务,有助于诊断项目中的大型编译周期。

请查看安装部分以安装Elixir,并阅读我们的入门指南以了解更多信息。