0
我認爲這個問題與詢問如何檢查值是否爲io_list
相同。我希望這樣做盡可能高效,因此不希望將該值轉換爲二進制文件,作爲檢查它是否爲io_list的一部分。如何測試一個Elixir(或erlang)值是否可以寫成二進制
我認爲這個問題與詢問如何檢查值是否爲io_list
相同。我希望這樣做盡可能高效,因此不希望將該值轉換爲二進制文件,作爲檢查它是否爲io_list的一部分。如何測試一個Elixir(或erlang)值是否可以寫成二進制
在瀏覽了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}
我不認爲有任何函數來檢查這一點,但我相信調用'iolist_size/1'的價值和醒目'ArgumentError'應該是相當快的。如果它引發'ArgumentError',它不是一個有效的iolist。 – Dogbert
不管你做什麼,爲了檢查是否是io_list,系統將不得不遍歷(可能的)io_list中的每個元素。你永遠不應該*不知道*你自己的程序產生了什麼數據。如果它是來自不可信來源的代碼,那麼您必須驗證它,無論如何,從那時起應該知道。真正的答案是在編譯時使用Dialyzer,而不是運行時檢查。 – zxq9