gpt4 book ai didi

elixir - erlang :now() deprecated in v18,什么是最好的转换

转载 作者:行者123 更新时间:2023-12-04 08:31:48 27 4
gpt4 key购买 nike

MongoDB driver的软件包中,我需要一个函数来生成唯一的文档ID。

此函数使用v18中不推荐使用的:erlang.now()
我寻求有关迁移的帮助,但没有成功。

我的实际代码(缩短):

defmodule MyModule_v17 do
use Bitwise, only_operators: true
def gen_trans_prefix do
{gs, s, ms} = :erlang.now
(gs * 1000000000000 + s * 1000000 + ms) &&& 281474976710655
end
end

最好的我想出了:
defmodule MyModule_v18 do
use Bitwise, only_operators: true
Kernel.if Keyword.get(:erlang.module_info, :exports) |> Enum.any?(fn({:system_time, 1}) -> true; (_) -> false end) do
def gen_trans_prefix do
:erlang.system_time(:micro_seconds) &&& 281474976710655
end
else
def gen_trans_prefix do
{gs, s, ms} = :erlang.now
(gs * 1000000000000 + s * 1000000 + ms) &&& 281474976710655
end
end
end

它可以完成工作,但是我不认为这是最好的方法。

有什么建议吗?

最佳答案

为了同时支持OTP 17和18(以及更高版本),您需要在编译时检测OTP版本。这是rebar.config for the lftpc project的示例:

{erl_opts, [
{platform_define, "(?=^[0-9]+)(?!^17$)", time_correction}
]}.

之所以执行此正则表达式检查,是因为OTP 17的发布标记了 semantic versioning(或接近它)的使用,因此小于OTP 17的任何版本的版本号都以R开头(例如R16)。

然后,在您的Erlang代码中,您可以执行类似 this的操作:
-ifdef(time_correction).
gen_trans_prefix() ->
{GS, S, MS} = erlang:timestamp(),
(GS * 1000000000000 + S * 1000000 + MS) band 281474976710655.
-else.
gen_trans_prefix() ->
{GS, S, MS} = erlang:now(),
(GS * 1000000000000 + S * 1000000 + MS) band 281474976710655.
-endif.

如果使用混合,则可以像在 erlc_options 中一样定义 mix.exs for the jose project:
def erlc_options do
extra_options = try do
case :erlang.list_to_integer(:erlang.system_info(:otp_release)) do
v when v >= 18 ->
[{:d, :time_correction}]
_ ->
[]
end
catch
_ ->
[]
end
extra_options
end

该项目的Erlang或Elixir代码可以引用 erlc_options(类似于您在问题中提到的解决方案):
defmodule MyModule do
use Bitwise, only_operators: true
if Enum.member?(Mix.Project.get!.project[:erlc_options] || [], {:d, :time_correction}) do
def gen_trans_prefix do
{gs, s, ms} = :erlang.timestamp
(gs * 1000000000000 + s * 1000000 + ms) &&& 281474976710655
end
else
def gen_trans_prefix do
{gs, s, ms} = :erlang.now
(gs * 1000000000000 + s * 1000000 + ms) &&& 281474976710655
end
end
end

关于elixir - erlang :now() deprecated in v18,什么是最好的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34023193/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com