4 未来潜在的不兼容性
4.1 介绍
本文档列出了 Erlang/OTP 中计划的未来潜在不兼容性。
4.2 OTP 27
Fun 创建者 pid 将始终是本地 init 进程
从 OTP 27 开始,函数 erlang:fun_info/1,2 将始终表示本地 init 进程创建了所有 fun,无论 fun 最初是在哪个进程或节点上创建的。
在 OTP 28 中,{pid,_} 元素将完全移除。
功能 maybe_expr 将默认启用
从 OTP 27 开始,maybe_expr 功能将被批准并默认启用。这意味着使用未引用的原子 maybe 的代码将无法编译。所有将 maybe 用作原子的用法都需要用引号引起来。或者,作为短期解决方案,可以禁用 maybe_expr 功能。
建议尽快将所有使用原子 maybe 的地方用引号引起来。编译器选项 warn_keywords 可用于发出关于所有未加引号的 maybe 出现的警告。
re 模块将使用不同的正则表达式引擎
模块 re 的功能目前由 PCRE 库提供,该库不再积极维护。因此,在 OTP 27 中,我们将切换到不同的正则表达式库。
re 模块使用的 PCRE 源代码已由 OTP 团队修改,以确保正则表达式匹配在匹配大型输入二进制文件或使用要求苛刻(回溯)的正则表达式时会产生结果。由于这些修改,迁移到 PCRE 的新版本一直是一个耗时的过程,因为所有修改都必须手动应用到更新的 PCRE 源代码中。
最有可能的是,新的正则表达式库将是 RE2。RE2 保证匹配时间与输入字符串的长度呈线性关系,并且它还避免递归以防止堆栈溢出。这应该可以使在不修改其源代码的情况下使用 RE2 成为可能。有关为什么 RE2 是一个好选择的信息,请参阅 WhyRE2。
此更改的一些影响是
我们预计 re 模块中的函数将继续得到支持,尽管某些选项可能会被停止。
只有对 UTF8 编码的二进制文件的模式匹配可能会得到支持(而不是 Latin1 编码的二进制文件)。
为了保证线性时间性能,RE2 不支持 PCRE 中正则表达式模式的所有结构。例如,不支持反向引用和环视断言。请参阅 Syntax,了解 RE2 支持的内容的描述。
编译正则表达式可能会变慢,因此通过在与正则表达式匹配之前显式地编译正则表达式,可以获得更多收益。
0.0 和 -0.0 将不再完全相等
目前,浮点数 0.0 和 -0.0 具有不同的内部表示。如果将其转换为二进制文件,则可以看出这一点
1> <<0.0/float>>. <<0,0,0,0,0,0,0,0>> 2> <<-0.0/float>>. <<128,0,0,0,0,0,0,0>>
但是,当它们相互匹配或使用 =:= 运算符进行比较时,它们被认为是相等的。因此,0.0 =:= -0.0 目前返回 true。
在 Erlang/OTP 27 中,0.0 =:= -0.0 将返回 false,而将 0.0 与 -0.0 匹配将失败。当用作映射键时,0.0 和 -0.0 将被视为不同的。
== 运算符将继续对 0.0 == -0.0 返回 true。
为了帮助查找可能需要修改的代码,在 OTP 27 中,当与 0.0 匹配或使用 =:= 运算符与该值进行比较时,将出现一个新的编译器警告。可以通过与 +0.0 而不是 0.0 匹配来抑制警告。
我们计划在 OTP 26.1 中引入相同的警告,但默认情况下它将被禁用。
单例类型变量将成为编译时错误
在 Erlang/OTP 26 之前,编译器会静默地接受以下规范
-spec f(Opts) -> term() when Opts :: {ok, Unknown} | {error, Unknown}. f(_) -> error.
在 OTP 26 中,编译器会发出警告,指出类型变量 Unknown 未绑定
t.erl:6:18: Warning: type variable 'Unknown' is only used once (is unbound) % 6| Opts :: {ok, Unknown} | {error, Unknown}. % | ^
在 OTP 27 中,该警告将成为错误。
Escripts 将默认编译
Escripts 将默认编译而不是解释。这意味着 compiler 应用程序必须可用。
可以通过在脚本文件中添加以下行来恢复解释 escripts 的旧行为
-mode(interpret).
在 OTP 28 中,对解释 escript 的支持将被移除。
-code_path_choice 将默认设置为 strict
此命令行选项控制在命令行、启动脚本和代码服务器中给出的路径应该是严格解释还是宽松解释。
OTP 26 及更早版本默认设置为 relaxed,这意味着 -pa myapp/ebin 将尝试加载 -pa myapp/ebin 和 -pa myapp/myapp/ebin。该选项将在 OTP 27 中默认设置为 strict。
存档回退将被移除
OTP 26 及更早版本允许应用程序将其部分目录作为普通文件夹,而其他目录作为存档。此功能以前由 reltool 使用,但从 OTP 26 开始不再是这种情况。在 OTP 27 中,将从代码服务器中移除对存档回退的支持。
三引号字符串
在 Erlang/OTP 27 之前,3 个或更多个双引号字符的序列将成对分组,每个对表示空字符串,如果数量为奇数,则最后一个字符是字符串的开头。然后,这些空字符串被连接起来,并有效地消失了。
在 Erlang/OTP 27 中;3 个或更多个双引号字符被解释为“三引号字符串”的开头。请参阅 EEP 64。
以下是一些代码示例,这些代码的含义将发生改变。请注意,在 Erlang/OTP 27.0 之前,所有这些示例都有些奇怪,因为没有充分的理由以这种方式编写代码。
"""String Content""" %% Was interpreted as "" "String Content" "" %% Which becomes "String Content" %% %% In OTP 27 it is instead a syntax error since no text is allowed %% on the line after an opening triple-quote
""" String Content """ %% Was interpreted as "" " String Content " "" %% Which becomes " String Content " %% %% In OTP 27 it is instead interpreted as a %% Triple-Quoted String equivalent to "String Content"
"""" ++ foo() ++ """" %% Became "" ++ foo() ++ "" %% %% In OTP 27 it is instead interpreted as a %% Triple-Quoted String (triple-or-more) equivalent to "++ foo() ++"
从 Erlang/OTP 26.1 到 26.2,编译器会对 3 个或更多个双引号字符的序列发出警告,因为这几乎肯定是一个错误,或者类似于错误的自动代码生成的结果。如果用户收到该警告,应更正代码,例如,在空字符串之间插入适当的空格,或完全删除多余的空格,这在 Erlang/OTP 27 之前和之后将具有相同的含义。
从 Erlang/OTP 26.2 到 27.0,这种情况得到改进,因此编译器改为对没有空格间隔的相邻字符串字面量发出警告,这在字符串开头实际上是相同的,但也涵盖了字符串结尾处的相同情况。
4.3 OTP 28
Fun 创建者 pid 将被移除
从 OTP 28 开始,函数 erlang:fun_info/1 将不包括 {pid,_} 元素,函数 erlang:fun_info/2 将不再接受 pid 作为第二个参数。
对解释 escripts 的支持将被移除
Escripts 将被编译,并且将不再可以通过使用指令 -mode(interpret) 来强制 escript 被解释。
4.4 OTP 29
将不再能够禁用功能 maybe_expr
从 OTP 29 开始,maybe_expr 功能将成为永久功能,并且将不再能够禁用。所有将 maybe 用作原子的用法都需要用引号引起来。
建议尽快将所有使用原子 maybe 的地方用引号引起来。编译器选项 warn_keywords 可用于发出关于所有未加引号的 maybe 出现的警告。