Symfoware

Symfowareについての考察blog

elixir入門 2.Basic types(データ型)

elixir入門 1.Introduction
この続きです。

今回は、この章を試してみます。
Basic types



Basic types



elixirで使用できるデータ型は以下の通り。

・integer
1, 0x1F

・float
1.0

・boolean
true, false

・atom / symbol
:atom

・string
"elixir"

・list
[1, 2, 3]

・tuple
{1, 2, 3}


それぞれ、使い方を見てみます。



Basic arithmetic



数値に使用できる演算子は、他の言語と同様、
+(加算), -(減算), *(乗算), /(除算)です。

iexを使って、動作を確認していきます。


iex(2)> 1 + 2
3
iex(3)> 10 - 3
7
iex(4)> 5 * 5
25
iex(5)> 10 / 2
5.0





割り算した時、割り切れる値であっても結果はfloat型になります。
integerで結果を取得したい場合は、「div」を使用します。
剰余を取得したい場合は「rem」を使用します。


iex(7)> div(10, 2)
5
iex(8)> div 10, 2 # カッコなしでもOK
5
iex(9)> div(10,3)
3
iex(10)> rem(10, 3) # 剰余
1





プリフィックスとして、0bをつけると2進数。
0oで8進数、0xで16進数となります。


iex(11)> 0b1010
10
iex(12)> 0o777
511
iex(13)> 0x1F
31





roundで四捨五入、truncで切り捨てです。
切り上げはFloat.ceilとします。


iex(15)> round 3.58
4
iex(16)> trunc 3.58
3
iex(17)> Float.ceil(1.1)
2.0








Booleans



真偽型として、trueとfalseが用意されています。


iex(18)> true
true
iex(19)> true == false
false




is_boolean関数で、値がboolean型であるか判定できます。


iex(20)> is_boolean(false)
true
iex(21)> is_boolean(0)
false



is_booleanの他に、データ型に応じたis_integer、is_float、is_numberが
用意されています。






Atoms



Atomとは、他の言語で言う定数でしょうか。


iex(22)> :hello
:hello
iex(23)> is_atom(:hello)
true
iex(24)> :hello == :world
false




Atomの:trueは、booleanのtrueと同義です。


iex(25)> true == :true
true
iex(26)> is_atom(false)
true
iex(27)> is_boolean(:false)
true







Strings



ダブルクオーテーションでくくった部分が文字列となります。
エンコーディングはUTF-8です。

※Windowsで実行する場合は、iexを実行する前に「chcp 65001」を実行して、
 UTF-8に文字コードを変更しておくと良いようです。


iex(28)> "hello"
"hello"




Atomを文字列として埋め込むこともできます。


iex(29)> "hello #{:world}"
"hello world"




文字列中に改行を含めると、改行コードは「\n」として出力されます。


iex(30)> "hello
...(30)> world"
"hello\nworld"
iex(31)> "hello\nworld"
"hello\nworld"




「改行コード」を「改行」として出力したい場合は、IO.putsを使用します。


iex(32)> IO.puts "hello\nworld"
hello
world
:ok



※最後に表示される「:ok」は、IO.puts関数の戻り値。



文字のバイト数を求めるには、byte_sizeを使用します。


iex(33)> byte_size("日本語でこんにちは")
27




文字数を求めたい場合は、String.length。


iex(34)> String.length("日本語でこんにちは")
9




大文字に変換したい場合は、String.upcase。


iex(35)> String.upcase("日本語でhello")
"日本語でHELLO"




文字列操作の詳細は、String moduleのドキュメントにまとめられています。
String module





Anonymous functions



fnとendキーワードで挟まれた区間は、無名関数となります。


iex(36)> add = fn a, b -> a + b end
#Function<12.54118792/2 in :erl_eval.expr/5>
iex(37)> is_function(add)
true
iex(38)> is_function(add, 2)
true
iex(39)> is_function(add, 1)
false
iex(40)> add.(1,2)
3
iex(41)> add(1,2)
** (RuntimeError) undefined function: add/2




引数が1つのis_functionは、その引数が関数オブジェクトであるかチェックします。
第2引数に数値を指定した場合、その関数が指定数の引数を取るかチェックします。

今回、addは引数を2つ取るので、

is_function(add, 2)はtrue
is_function(add, 1)はfalse
となりました。

作成した無名関数を実行するには、

関数名 + 「.」 + (引数)

と指定します。

「.」を忘れた場合は、エラーが発生します。



無名関数は、他の無名関数で使用することもできます。


iex(41)> add_two = fn a -> add.(a, 2) end
#Function<6.54118792/1 in :erl_eval.expr/5>
iex(42)> add_two.(5)
7




無名関数内の数値は、グローバル領域の変数を汚染しません。


iex(43)> x = 42
42
iex(44)> (fn -> x = 2 end).()
2
iex(45)> x
42







(Linked) Lists



[]でくくられた範囲がリストとなります。
リストには、別の型の値を含めることができます。

lengthで、リストの長さを知ることができます。


iex(46)> [1, 2, true, 3]
[1, 2, true, 3]
iex(47)> length [1, 2, true, 3]
4




++, --演算子を使用することで、リストの加算、減算を行うことができます。


iex(48)> [1,2,3] ++ [4,5,6]
[1, 2, 3, 4, 5, 6]
iex(49)> [1,2,3] ++ [1,2,3]
[1, 2, 3, 1, 2, 3]
iex(50)> [1, true, 2, false, 3, true] -- [true, false]
[1, 2, 3, true]




hdでリストの先頭、tlでリストの先頭を除いたリストが取得できます。


iex(52)> hd(list)
1
iex(53)> tl(list)
[2, 3]




hdに空のリストを渡した場合エラーとなります。


iex(54)> hd []
** (ArgumentError) argument error
    :erlang.hd([])





リストがASCIIコード範囲の数値で構成される場合、シングルクォートで
くくられた値が返されます。


iex(54)> [11, 12, 13]
'\v\f\r'
iex(55)> [11, 12, 13, true]
[11, 12, 13, true]
iex(56)> [104, 101, 108, 108, 111]
'hello'




これは文字列ではないため、以下の比較は失敗します。


iex(57)> 'hello' == "hello"
false




詳細はこちらのドキュメントに記載されています。
Binaries, strings and char lists

※チュートリアルの6章なので、そのうち内容を確認します。





Tuples



{}でくくられた範囲がタプルとなります。
tuple_sizeでサイズがわかります。


iex(58)> {:ok, "hello"}
{:ok, "hello"}
iex(59)> tuple_size({:ok, "hello"})
2




elem(タブル, 取得するインデックス)で指定位置の要素を取得できます。
取り出しても要素は削除されません。


iex(61)> elem(tuple, 1)
"hello"
iex(62)> tuple_size(tuple)
2




put_elem(タプル, 置き換えるインデックス, 値)で
指定位置の要素を変更できます。
この動作は非破壊的で、実行後も要素本体は書き換えられません。
書き換わったタプルが戻り値として与えられるだけです。


iex(63)> tuple = {:ok, "hello"}
{:ok, "hello"}
iex(64)> put_elem(tuple, 1, "world")
{:ok, "world"}
iex(65)> tuple
{:ok, "hello"}






Lists or tuples?



リストとタプルの違いは何か?
リストは、リスト内にさらにリストを指定することができます。
また、要素の追加も行えます。


iex(66)> list = [1|[2|[3|[]]]]
[1, 2, 3]
iex(67)> [0] ++ list
[0, 1, 2, 3]
iex(68)> list ++ [4]
[1, 2, 3, 4]





タプルは、Erlangのパターンマッチを使用した処理で威力を発揮します。
例えば、ファイルが読み込めたか。


iex(69)> File.read("sample.exs")
{:ok, "IO.puts \"Hello world\nfrom Elixir\"\n"}
iex(70)> File.read("nothing")
{:error, :enoent}



{:ok, ...}にマッチすればファイルが読み込めたと簡単に判定できますね。

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2015/07/25(土) 21:55:28|
  2. Erlang
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<elixir入門 3.Basic operators(演算子) | ホーム | elixir入門 1.Introduction>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1762-5dae0ef5
この記事にトラックバックする(FC2ブログユーザー)