查看源代码 兼容性和弃用
Elixir 的版本号遵循 vMAJOR.MINOR.PATCH 的模式。
Elixir 目前处于 v1 的主版本。每 6 个月会发布一个新的向后兼容的次要版本。补丁版本没有固定的发布计划,只有在修复 bug 或安全漏洞时才会发布。
Elixir 只会对最新的次要分支应用 bug 修复。安全补丁适用于最近 5 个次要分支。
Elixir 版本 | 支持 |
---|---|
1.16 | bug 修复和安全补丁 |
1.15 | 仅安全补丁 |
1.14 | 仅安全补丁 |
1.13 | 仅安全补丁 |
1.12 | 仅安全补丁 |
新版本会在只读的 公告邮件列表 中发布。所有安全版本 都会被标记为 [security]
。
目前没有计划发布 v2 主版本。
非主版本 Elixir 版本之间的兼容性
Elixir 的次要版本和补丁版本是向后兼容的:在某个特定版本中定义良好的行为和文档化的 API 将在未来的版本中继续起作用。
虽然我们预计绝大多数程序在未来会保持兼容,但无法保证未来的任何更改都不会导致程序中断。在一些不太可能的情况下,我们可能会引入会破坏现有代码的更改。
安全:实现中可能会出现安全问题,其解决方案需要向后不兼容的更改。我们保留解决此类安全问题的权利。
bug:如果 API 的行为不符合预期,依赖于错误行为的程序在修复 bug 后可能会中断。我们保留修复此类 bug 的权利。
编译器前端:可能会对编译器进行改进,引入对模糊模式的新警告并提供更详细的错误消息。这些可能会导致编译错误(在使用
--warning-as-errors
运行时)或在断言特定错误消息时导致工具故障(虽然应该避免这种情况)。我们保留进行此类改进的权利。导入:可能会向
Kernel
模块添加新函数,该模块是自动导入的。它们可能会与您模块中定义的本地函数发生冲突。可以使用import Kernel, except: [...]
(其中包含您不想从Kernel
导入的所有函数的列表)以向后兼容的方式解决冲突。我们保留进行此类添加的权利。
为了在不引入破坏性更改的情况下继续发展语言,Elixir 将依靠弃用机制来降低某些实践的使用并推广新的实践。我们的弃用策略在 “弃用”部分 中概述。
上述兼容性保证的唯一例外是实验性功能,这些功能将被明确标记为实验性,并且在稳定之前不提供任何兼容性保证。
Elixir 与 Erlang/OTP 之间的兼容性
Erlang/OTP 的版本控制独立于 Elixir 的版本控制。Erlang 每年都会发布一个新的主版本。我们的目标是在 Elixir 发布时支持最新的三个 Erlang 主版本。兼容性表如下所示。
Elixir 版本 | 支持的 Erlang/OTP 版本 |
---|---|
1.16 | 24 - 26 |
1.15 | 24 - 26 |
1.14 | 23 - 25(以及 v1.14.5 中的 Erlang/OTP 26) |
1.13 | 22 - 24(以及 v1.13.4 中的 Erlang/OTP 25) |
1.12 | 22 - 24 |
1.11 | 21 - 23(以及 v1.11.4 中的 Erlang/OTP 24) |
1.10 | 21 - 22(以及 v1.10.3 中的 Erlang/OTP 23) |
1.9 | 20 - 22 |
1.8 | 20 - 22 |
1.7 | 19 - 22 |
1.6 | 19 - 20(以及 v1.6.6 中的 Erlang/OTP 21) |
1.5 | 18 - 20 |
1.4 | 18 - 19(以及 v1.4.5 中的 Erlang/OTP 20) |
1.3 | 18 - 19 |
1.2 | 18 - 18(以及 v1.2.6 中的 Erlang/OTP 19) |
1.1 | 17 - 18 |
1.0 | 17 - 17(以及 v1.0.5 中的 Erlang/OTP 18) |
Elixir 可能会在补丁版本中添加对新 Erlang/OTP 版本的兼容性,例如 v1.4.5 中对 Erlang/OTP 20 的支持。这些版本是为了方便而发布的,通常包含 Elixir 无需错误运行所需的最小更改(如果有)。只有下一个次要版本,在本例中为 v1.5.0,才会有效地利用最新 Erlang/OTP 版本提供的功能。
弃用
策略
Elixir 的弃用机制分为 3 个步骤。
功能被软弃用。这意味着 CHANGELOG 和文档必须将功能列为已弃用,但运行代码时不会发出实际的警告。软弃用功能不是强制性的。
功能被实际弃用,在使用时会发出警告。这也被称为硬弃用。为了弃用功能,建议的替代方案必须存在至少三个次要版本。例如,
Enum.uniq/2
在 Elixir v1.1 中被软弃用,建议使用Enum.uniq_by/2
。这意味着 Elixir v1.4 或更高版本才会发出弃用警告。功能被移除。这只能在主版本中发生。这意味着 Elixir v1.x 中的已弃用功能只能在 Elixir v2.x 中移除。
弃用表
第一列是功能被硬弃用的版本。第二列简要描述了已弃用的功能,第三列解释了替代方案以及替代方案可用的版本。
版本 | 已弃用的功能 | 替代方案(自版本起可用) |
---|---|---|
v1.16 | ~R/.../ | ~r/.../ (v1.0) |
v1.16 | Enum.slice/2 中具有负步长的范围 | 范围中的显式步长 (v1.11) |
v1.16 | String.slice/2 中具有负步长的范围 | 范围中的显式步长 (v1.11) |
v1.15 | Calendar.ISO.day_of_week/3 | Calendar.ISO.day_of_week/4 (v1.11) |
v1.15 | Exception.exception?/1 | Kernel.is_exception/1 (v1.11) |
v1.15 | Regex.regex?/1 | Kernel.is_struct/2 (Kernel.is_struct(term, Regex) ) (v1.11) |
v1.15 | Logger.warn/2 | Logger.warning/2 (v1.11) |
v1.14 | use Bitwise | import Bitwise (v1.0) |
v1.14 | ~~~/1 | bnot/2 (v1.0) |
v1.14 | Application.get_env/3 和类似函数在模块体中 | Application.compile_env/3 (v1.10) |
v1.14 | String.starts_with?/2 中的编译模式 | 传递字符串列表 (v1.0) |
v1.14 | Mix.Tasks.Xref.calls/1 | 编译跟踪器(在 Code 中概述) (v1.10) |
v1.14 | $levelpad 在 Logger 中 | 无 |
v1.14 | <|> 作为自定义运算符 | 另一个自定义运算符 (v1.0) |
v1.13 | ! 和 != 在版本要求中 | ~> 或 >= (v1.0) |
v1.13 | Mix.Config | Config (v1.9) |
v1.13 | :strip_beam 配置到 mix escript.build | :strip_beams (v1.9) |
v1.13 | Macro.to_string/2 | Macro.to_string/1 (v1.0) |
v1.13 | System.get_pid/0 | System.pid/0 (v1.9) |
v1.12 | ^^^/2 | bxor/2 (v1.0) |
v1.12 | @foo() 用于读取模块属性 | 删除括号 (v1.0) |
v1.12 | use EEx.Engine | 明确委托给 EEx.Engine (v1.0) |
v1.12 | :xref 编译器在 Mix 中 | 无(它现在始终作为编译器的一部分运行) |
v1.11 | Mix.Project.compile/2 | Mix.Task.run("compile", args) (v1.0) |
v1.11 | Supervisor.Spec.worker/3 和 Supervisor.Spec.supervisor/3 | Supervisor 中概述的新子进程规范 (v1.5) |
v1.11 | Supervisor.start_child/2 和 Supervisor.terminate_child/2 | DynamicSupervisor (v1.6) |
v1.11 | System.stacktrace/1 | __STACKTRACE__ 在 try/catch/rescue 中 (v1.7) |
v1.10 | Code.ensure_compiled?/1 | Code.ensure_compiled/1 (v1.0) |
v1.10 | Code.load_file/2 | Code.require_file/2 (v1.0) 或 Code.compile_file/2 (v1.7) |
v1.10 | Code.loaded_files/0 | Code.required_files/0 (v1.7) |
v1.10 | Code.unload_file/1 | Code.unrequire_files/1 (v1.7) |
v1.10 | 向 Logger.log/2 传递非字符数据 | 使用 to_string/1 显式转换为字符串 (v1.0) |
v1.10 | :compile_time_purge_level 在 Logger 应用程序环境中 | :compile_time_purge_matching 在 Logger 应用程序环境中 (v1.7) |
v1.10 | Supervisor.Spec.supervise/2 | Supervisor 中概述的新子进程规范 (v1.5) |
v1.10 | :simple_one_for_one 策略在 Supervisor 中 | DynamicSupervisor (v1.6) |
v1.10 | :restart 和 :shutdown 在 Task.Supervisor.start_link/1 中 | :restart 和 :shutdown 在 Task.Supervisor.start_child/3 中 (v1.6) |
v1.9 | Map.drop/2 、Map.split/2 和 Map.take/2 中的可枚举键 | 预先对第二个参数调用 Enum.to_list/1 (v1.0) |
v1.9 | Mix.Project.load_paths/1 | Mix.Project.compile_path/1 (v1.0) |
v1.9 | 向 String.replace/4 传递 :insert_replaced | 使用 :binary.replace/4 (v1.0) |
v1.8 | 向 Collectable.into/1 传递非空列表 | ++/2 或 Keyword.merge/2 (v1.0) |
v1.8 | 向 for/1 中的 :into 传递非空列表 | ++/2 或 Keyword.merge/2 (v1.0) |
v1.8 | 向 Enum.into/2 传递非空列表 | ++/2 或 Keyword.merge/2 (v1.0) |
v1.8 | 时间单位使用复数形式,例如::seconds 、:milliseconds 等 | 使用单数形式,例如::second 、:millisecond 等 (v1.4) |
v1.8 | Inspect.Algebra.surround/3 | Inspect.Algebra.concat/2 和 Inspect.Algebra.nest/2 (v1.0) |
v1.8 | Inspect.Algebra.surround_many/6 | Inspect.Algebra.container_doc/6 (v1.6) |
v1.9 | --detached 在 Kernel.CLI 中 | --erl "-detached" (v1.0) |
v1.8 | Kernel.ParallelCompiler.files/2 | Kernel.ParallelCompiler.compile/2 (v1.6) |
v1.8 | Kernel.ParallelCompiler.files_to_path/2 | Kernel.ParallelCompiler.compile_to_path/2 (v1.6) |
v1.8 | Kernel.ParallelRequire.files/2 | Kernel.ParallelCompiler.require/2 (v1.6) |
v1.8 | 从 Mix.Compilers.Erlang.compile/6 的回调中返回 {:ok, contents} 或 :error | 返回 {:ok, contents, warnings} 或 {:error, errors, warnings} (v1.6) |
v1.8 | System.cwd/0 和 System.cwd!/0 | File.cwd/0 和 File.cwd!/0 (v1.0) |
v1.7 | Code.get_docs/2 | Code.fetch_docs/1 (v1.7) |
v1.7 | Enum.chunk/2,3,4 | Enum.chunk_every/2 和 Enum.chunk_every/3,4 (v1.5) |
v1.7 | 在 GenServer 回调中调用 super/1 | 在不调用 super/1 的情况下显式实现行为 (v1.0) |
v1.7 | 不在右边 | left not in right (v1.5) |
v1.7 | Registry.start_link/3 | Registry.start_link/1 (v1.5) |
v1.7 | Stream.chunk/2,3,4 | Stream.chunk_every/2 和 Stream.chunk_every/3,4 (v1.5) |
v1.6 | Enum.partition/2 | Enum.split_with/2 (v1.4) |
v1.6 | Macro.unescape_tokens/1,2 | 使用 Enum.map/2 遍历参数 (v1.0) |
v1.6 | Module.add_doc/6 | @doc 模块属性 (v1.0) |
v1.6 | Range.range?/1 | 与 _.._ 模式匹配 (v1.0) |
v1.5 | () 代表 nil | nil (v1.0) |
v1.5 | char_list/0 类型 | charlist/0 类型 (v1.3) |
v1.5 | Atom.to_char_list/1 | Atom.to_charlist/1 (v1.3) |
v1.5 | Enum.filter_map/3 | Enum.filter/2 + Enum.map/2 或 for/1 推导式 (v1.0) |
v1.5 | Float.to_char_list/1 | Float.to_charlist/1 (v1.3) |
v1.5 | GenEvent 模块 | Supervisor 和 GenServer (v1.0);<br/>GenStage (v1.3);<br/>:gen_event (Erlang/OTP 17) |
v1.5 | <%= 在 EEx 中的中间和结束表达式中 | 使用 <% (<%= 仅允许在开始表达式中) (v1.0) |
v1.5 | :as_char_lists 值在 Inspect.Opts.t/0 类型中 | :as_charlists 值 (v1.3) |
v1.5 | :char_lists 键在 Inspect.Opts.t/0 类型中 | :charlists 键 (v1.3) |
v1.5 | Integer.to_char_list/1,2 | Integer.to_charlist/1 和 Integer.to_charlist/2 (v1.3) |
v1.5 | to_char_list/1 | to_charlist/1 (v1.3) |
v1.5 | List.Chars.to_char_list/1 | List.Chars.to_charlist/1 (v1.3) |
v1.5 | @compile {:parse_transform, _} 在 Module 中 | 无 |
v1.5 | Stream.filter_map/3 | Stream.filter/2 + Stream.map/2 (v1.0) |
v1.5 | String.ljust/3 和 String.rjust/3 | 使用 String.pad_leading/3 和 String.pad_trailing/3 以及二进制填充 (v1.3) |
v1.5 | String.lstrip/1 和 String.rstrip/1 | String.trim_leading/1 和 String.trim_trailing/1 (v1.3) |
v1.5 | String.lstrip/2 和 String.rstrip/2 | 使用 String.trim_leading/2 和 String.trim_trailing/2 以及二进制作为第二个参数 (v1.3) |
v1.5 | String.strip/1 和 String.strip/2 | String.trim/1 和 String.trim/2 (v1.3) |
v1.5 | String.to_char_list/1 | String.to_charlist/1 (v1.3) |
v1.4 | 在 -> 之后没有表达式的匿名函数 | 使用表达式或显式返回 nil (v1.0) |
v1.4 | 支持使 私有函数 可重写 | 使用 公共函数 (v1.0) |
v1.4 | 用作函数调用的变量 | 使用圆括号 (v1.0) |
v1.4 | Access.key/1 | Access.key/2 (v1.3) |
v1.4 | Behaviour 模块 | @callback 模块属性 (v1.0) |
v1.4 | Enum.uniq/2 | Enum.uniq_by/2 (v1.2) |
v1.4 | Float.to_char_list/2 | :erlang.float_to_list/2 (Erlang/OTP 17) |
v1.4 | Float.to_string/2 | :erlang.float_to_binary/2 (Erlang/OTP 17) |
v1.4 | HashDict 模块 | Map (v1.2) |
v1.4 | HashSet 模块 | MapSet (v1.1) |
v1.4 | IEx.Helpers.import_file/2 | IEx.Helpers.import_file_if_available/1 (v1.3) |
v1.4 | Mix.Utils.camelize/1 | Macro.camelize/1 (v1.2) |
v1.4 | Mix.Utils.underscore/1 | Macro.underscore/1 (v1.2) |
v1.4 | 在 OptionParser 中的多个字母别名 | 使用单个字母别名 (v1.0) |
v1.4 | Set 模块 | MapSet (v1.1) |
v1.4 | Stream.uniq/2 | Stream.uniq_by/2 (v1.2) |
v1.3 | \x{X*} 在字符串/标识/字符列表中 | \uXXXX 或 \u{X*} (v1.1) |
v1.3 | Dict 模块 | Keyword (v1.0) 或 Map (v1.2) |
v1.3 | :append_first 选项在 defdelegate/2 中 | 显式定义函数 (v1.0) |
v1.3 | 在 Enum.group_by/3 中作为第二个参数的映射/字典 | Enum.reduce/3 (v1.0) |
v1.3 | Keyword.size/1 | length/1 (v1.0) |
v1.3 | Map.size/1 | map_size/1 (v1.0) |
v1.3 | /r 选项在 Regex 中 | /U (v1.1) |
v1.3 | Set 行为 | MapSet 数据结构 (v1.1) |
v1.3 | String.valid_character?/1 | String.valid?/1 (v1.0) |
v1.3 | Task.find/2 | 使用直接消息匹配 (v1.0) |
v1.3 | 在 URI.decode_query/2 中作为第二个参数的非映射 | 使用映射 (v1.0) |
v1.2 | Dict 行为 | Map 和 Keyword (v1.0) |
v1.1 | ?\xHEX | 0xHEX (v1.0) |
v1.1 | Access 协议 | Access 行为 (v1.1) |
v1.1 | as: true | false 在 alias/2 和 require/2 中 | 无 |