檢視原始碼 即將發生的潛在不相容性
簡介
本文檔列出了 Erlang/OTP 中計畫的即將發生的潛在不相容性。
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
出現的警告。
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 中,該警告將變成錯誤。
Escript 將預設編譯
Escript 將預設編譯而不是解釋。這表示必須提供 compiler
應用程式。
可以透過在指令碼檔案中新增以下行來還原解釋 escript 的舊行為
-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 到 27.0,編譯器會針對 3 個或更多雙引號字元的序列發出警告,因為這幾乎可以肯定是錯誤或類似於糟糕的自動程式碼產生結果。如果使用者收到該警告,則應更正程式碼,例如在空字串之間插入適當的空格,或完全刪除多餘的字串,這將在 Erlang/OTP 27 前後具有相同的含義。
OTP 28
re 模組將使用不同的正規表示式引擎
模組 re
的功能目前由 PCRE 程式庫提供,該程式庫不再積極維護。因此,在 OTP 28 中,我們將切換到不同的正規表示式程式庫。
OTP 團隊修改了 re
模組使用的 PCRE 原始碼,以確保在匹配巨大的輸入二進制檔案和/或使用高要求的(回溯)正規表示式時,正規表示式匹配會產生結果。由於這些修改,遷移到新版本的 PCRE 一直是一個耗時的過程,因為所有修改都必須再次手動應用於更新的 PCRE 原始碼。
最有可能的是,新的正規表示式程式庫將會是 RE2。RE2 保證匹配時間與輸入字串的長度呈線性關係,並且它也會避開遞迴以避免堆疊溢位。這應該可以使在不修改其原始碼的情況下使用 RE2。有關為什麼 RE2 是一個好選擇的更多資訊,請參閱 WhyRE2。
此變更的一些影響如下
- 我們預計將繼續支援
re
模組中的函數,儘管某些選項可能會停止使用。 - 很可能只會支援 UTF8 編碼二進制檔案的模式比對(而不是 Latin1 編碼的二進制檔案)。
- 為了保證線性時間效能,RE2 並不支援 PCRE 中正規表示式模式的所有結構。例如,不支援反向參考和環顧斷言。請參閱 Syntax 以了解 RE2 支援的內容。
- 編譯正規表示式可能會比較慢,因此在與正規表示式匹配之前明確編譯它會獲得更多好處。
將移除 Fun 建立者 pid
從 OTP 28 開始,函數 erlang:fun_info/1
將不包含 {pid,_}
元素,並且函數 erlang:fun_info/2
將不再接受 pid
作為第二個引數。
將移除對解釋 escript 的支援
Escript 將被編譯,並且將不再可能透過使用指令 -mode(interpret)
來強制解釋 escript。
OTP 29
將不再可能停用功能 maybe_expr
從 OTP 29 開始,maybe_expr
功能將變成永久性的,並且不再可能停用。所有將 maybe
作為原子的用法都需要加上引號。
建議盡快為所有使用原子 maybe
的地方加上引號。編譯器選項 warn_keywords
可用於發出關於所有未加引號的 maybe
出現的警告。
cprof 和 eprof 將由 tprof 取代
從 OTP 29 開始,將會移除 cprof
和 eprof
,而改用 OTP 27 中新增的 tprof
。