2017-09-27 64 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} 
相關問題