この節ではバイナリとビットシンタックス(ビット構文)について学びます。
初心者の方はあまり使う機会がないと思うので飛ばして頂いて大丈夫です。このサイトでバイナリ等が利用されるのは、
ネットワークを介した通信に関する部分以降です。
バイナリは2進数で構成されたデータ構造です。これはErlang特有のデータ型ではなく、コンピュータ共通の概念です。
コンピュータは2進数のデータを理解して様々な動作をしているため、バイナリはコンピュータが直接認識できるデータ型だと
言えます。
詳しいことについては、Wikipedia バイナリに
解説を譲ります。
先述した通り、Erlangにおいてバイナリは1バイトの配列のように扱われるのですが、バイトは
そもそもbitの配列のようなものです。
したがって、正確にはバイナリはbitの配列だと言うことが可能です。
バイトで表記されるのは人間にとって理解しやすい形だからです。
バイナリデータを見てみましょう。
1> <<10,20>>.
<<10,20>>
2> <<"ABC">>.
<<"ABC">>
1> <<1:1,0:1>>.
<<2:2>>
バイナリから構成される書式は次のようになっています。
<<E1, E2, ... En>>
E1 ~ En はバイナリデータです。したがって、0 ~ 255 を表現することが可能です。
また、文字列はasciiコードの配列ですので、そのまま表現することが可能です。
より詳細にbitレベルで指定することも可能です。その場合は次のような書式になります。
このような記述方法のことをビットシンタックスと呼びます。
<<Value1:Size1, Value2:Size2, ... Value_n:Size_n>>
Sizeが使用するbitの数数で、Valueが値です。Sizeによって指定できるValueの範囲が変わってきます。
「0から2のSize乗-1」までが指定できる範囲です。
ビットシンタックスで可能なことを確認してみます。また、確認のためにバイナリのサンプルも記載しておきます。
1> Bin1 = <<1,17,42>>.
<<1,17,42>>
2> Bin2 = <<"abc">>.
<<97,98,99>>
3> Bin3 = <<1,17,42:16>>.
<<1,17,0,42>>
4> <<A,B,C:16>> = <<1,17,42:16>>.
<<1,17,0,42>>
5> C.
42
6> <<D:16,E,F>> = <<1,17,42:16>>.
<<1,17,0,42>>
7> D.
273
8> F.
42
また、ビットシンタックスではタイプ限定子(type specifier list)を利用することが可能です。
これは以下のように利用します。
Value/TypeSpecifierList
Value:Size/TypeSpecifierList
タイプ限定子としては、integer,float,binary,bytes,bitstring,bitsが存在します。
また、符号の扱いとして signed,unsigned
バイナリ列の構成順序であるエンディアン big,little,native
も存在します。
これらがバイナリでどのように表現されているかは専門書籍(
コンピュータの設計と構成 上
など)に譲ります。
比較的簡単なものだけサンプルとして掲載します。
9> <<G,H/binary>> = <<1,17,42:16>>.
<<1,17,0,42>>
10> H.
<<17,0,42>>
11> <<G,H/bitstring>> = <<1,17,42:12>>.
<<1,17,1,10:4>>
12> H.
<<17,1,10:4>>
ビットシンタックスを利用する際に注意しなければならない点があります。
次のような表記はエラーとなってしまいます。
B=<<1>>
これは予想している形とは異なり、Erlangに以下のように解釈されてしまっているためです。
B =< <1>>
符号'='の左右にはスペースを空ける習慣を付ける必要があります。
最後にバイナリに関するBIFを取り扱います。以下の関数はerlangモジュールに付随しています。
size(Item)
Itemのサイズを返す。Itemはタプル、もしくはバイナリである必要がある。
> size(<<1,2,3>>).
3
> size(<<"hello world">>).
11
iolist_size(Item)
バイナリのサイズを得ます。
> iolist_size([1,2|<<3,4>>]).
4
is_binary(Term)
タームTermがバイナリであればtrue、そうでなければfalseを返します。
is_bitstring(Term)
タームTermがもし、ビット文字列(バイナリも含む)であればtrue、
そうでなければfalseを返します。
term_to_binary(Term)
タームTermをバイナリに変換する。
Bin = term_to_binary({1,2,[3,4,5],6}).
<<131,104,4,97,1,97,2,107,0,3,3,4,5,97,6>>
binary_to_term(Binary)
バイナリ形式からタームに変換される。
> binary_to_term(Bin).
{1,2,[3,4,5],6}
binary_to_list(Binary)
バイナリ形式からリスト形式に変換する。
> binary_to_list(<<1,2,3,4>>).
[1,2,3,4]
> binary_to_list(<<"hello world">>).
"hello world"
binary_to_list(Binary, Start, Stop)
範囲を指定して、バイナリ形式からリスト形式に変換する。
> binary_to_list(<<"hello world">>,3,8).
"llo wo"
list_to_binary(IoList)
Listに格納されている値が整数かバイナリである場合、それらを結合してバイナリを返す。
> Bin1 = <<1,2,3>>.
<<1,2,3>>
> Bin2 = <<4,5>>.
<<4,5>>
> Bin3 = <<6>>.
<<6>>
> list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]).
<<1,2,3,1,2,3,4,5,4,6>>
iolist_to_binary(IoListOrBinary)
整数とバイナリを組み合わせて、新たなバイナリを作成します。