如何测试Elixir(或erlang)值是否可以写入二进制
我认为这个问题与询问如何检查值是否为如何测试Elixir(或erlang)值是否可以写入二进制,erlang,elixir,Erlang,Elixir,我认为这个问题与询问如何检查值是否为io\u列表相同。我希望这是尽可能有效的,因此不希望将值转换为二进制作为检查它是否是io_列表的过程的一部分 浏览Erlang的stdlib后,我相信您最好的选择是使用:Erlang.iolist\u size和catchArgumentError来检测无效的iolist iolist? = fn x -> try do :erlang.iolist_size(x) true rescue ArgumentError -&
io\u列表
相同。我希望这是尽可能有效的,因此不希望将值转换为二进制作为检查它是否是io_列表的过程的一部分 浏览Erlang的stdlib后,我相信您最好的选择是使用:Erlang.iolist\u size
和catchArgumentError
来检测无效的iolist
iolist? = fn x ->
try do
:erlang.iolist_size(x)
true
rescue
ArgumentError -> false
end
end
IO.inspect iolist?("foo")
IO.inspect iolist?(["foo"])
IO.inspect iolist?(:foo)
输出:
true
true
false
在我高度不科学的基准测试中,这大约是:erlang.iolist_to_binary/1
的三倍
iolist = List.duplicate([[[1, "2"], '3'], ?4], 1000000)
IO.inspect :timer.tc(:erlang, :iolist_to_binary, [iolist])
IO.inspect :timer.tc(:erlang, :iolist_size, [iolist])
{82291,
}
{25577, 4000000}
我认为没有任何函数可以检查这一点,但我相信调用iolist\u size/1
值并捕获ArgumentError
应该非常快。如果它引发ArgumentError
,则它不是有效的iolist。无论您做什么,要检查该对象是否是io列表,系统必须迭代(可能)io列表中的每个元素。您永远不应该不知道自己的程序生成了什么数据。如果它是来自不可信源的代码,您必须验证它,并且从那时起应该知道。这里真正的答案是在编译时使用透析器,而不是执行运行时检查。
{82291,
<<1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1,
50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1, 50, 51, 52, 1,
50, 51, 52, 1, 50, 51, 52, 1, ...>>}
{25577, 4000000}