2017-09-27 3 views
0

이 질문은 값이 io_list인지 확인하는 방법과 같은 질문이라고 생각합니다. 나는 이것이 가능한 한 효율적이기를 바란다. 따라서 io_list인지 체크하는 과정의 한 부분으로 값을 바이너리로 변환하고 싶지는 않을 것이다.엘릭서 (또는 erlang) 값을 바이너리로 쓸 수 있는지 테스트하는 방법

+0

나는이를 확인하기 위해 어떤 기능이 있다고 생각하지 않습니다,하지만 난 값을 1'/iolist_size'호출하고 ArgumentError'가 꽤 빨리해야한다'잡기 믿습니다. ArgumentError가 발생하면 유효한 아이톨리스트가 아닙니다. – Dogbert

+2

당신이 무엇을 하든지, 그 것이 io_list인지 확인하려면 시스템이 가능한 (가능한) io_list의 모든 요소를 ​​반복해야합니다. 자신의 프로그램이 생성 한 데이터를 결코 * 알지 못한다. 신뢰할 수없는 출처의 코드 인 경우 반드시 * 검증해야하며 그 시점부터 알고 있어야합니다. 진짜 대답은 컴파일 타임에 Dialyzer를 사용하는 것입니다. 런타임 검사는하지 않습니다. – zxq9

답변

1

얼랑 (Erlang)의 stdlib을 살펴본 후 :erlang.iolist_size을 사용하고 ArgumentError을 잡아 잘못된 iolists를 찾아내는 것이 최선의 선택이라고 생각합니다.

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}