2017-09-27 27 views
0

我认为这个问题与询问如何检查值是否为io_list相同。我希望这样做尽可能高效,因此不希望将该值转换为二进制文件,作为检查它是否为io_list的一部分。如何测试一个Elixir(或erlang)值是否可以写成二进制

+0

我不认为有任何函数来检查这一点,但我相信调用'iolist_size/1'的价值和醒目'ArgumentError'应该是相当快的。如果它引发'ArgumentError',它不是一个有效的iolist。 – Dogbert

+2

不管你做什么,为了检查是否是io_list,系统将不得不遍历(可能的)io_list中的每个元素。你永远不应该*不知道*你自己的程序产生了什么数据。如果它是来自不可信来源的代码,那么您必须验证它,无论如何,从那时起应该知道。真正的答案是在编译时使用Dialyzer,而不是运行时检查。 – zxq9

回答

1

在浏览了Erlang的stdlib之后,我相信你的最佳选择是使用:erlang.iolist_size并捕获ArgumentError来检测无效的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, 
<<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} 
相关问题