基本
数値演算
通常の四則演算
1 + 2
5 - 3
10 * 5
7 / 3
整数で商と余りを計算する場合
div(7, 3)
rem(7, 3)
文字列
ダブルクォーテーションで囲むと String
"Hello"
シングルクォーテーションで囲むと Character List
'Hello'
Character List は文字コードの配列
'Hello'
|> Enum.map(&IO.inspect(&1))
String と Character List は異なる
'Hello' == "Hello"
atom型
変数名 = 値 になっている
:foo
:foo == :foo
:foo == :bar
is_atom で atom 型かどうか確認できる
is_atom(:foo)
boolean は atom 型になっている
is_atom(true)
変数
Elixir では変数に値を「代入」(アサイン)しない
変数を指定したパターンにマッチするよう「束縛」(バインド)する
=
で変数を束縛する
a = 1
束縛された変数はそのパターンを返す
a
=
はパターンにマッチしているかを判定する
1 = a
マッチしない場合、 MatchError が発生する
2 = a
同じ変数に別のパターンを再束縛することができる
代入とは違い、同じ名前の別変数が新しく定義されている
a = 5
a
再束縛ではなくパターンマッチさせたい場合、ピン演算子 ^
を使う
^a = 5
^a = 7
a
比較演算子で比較できる
a = 1
b = 2
a == b
a < b
a + 1 == b
文字列の中で式展開できる
a = "Elixir"
"Hello #{a}"
<>
で文字列を結合できる
"Hello" <> " " <> a
不変(イミュータブル)
Elixir などの開発言語は全ての変数が不変(イミュータブル)になっている
変更可能(ミュータブル)だと、、、
a = [1, 2, 3]
do_something(a)
a == [1, 2, 3] # 保証できない
do_something の中で a に対して破壊的な変更(要素の削除、ソートなど)が加えられたとき、
呼び出し元からはそのことが予測できない
不変(イミュータブル)だと、、、
a = [1, 2, 3]
b = do_something(a)
a == [1, 2, 3] # 保証できる
do_something で何をしようと、 a は変更できない
呼び出し先で更新されてしまうことによるバグが防げる
また、ミュータブルよりもイミュータブルの方がメモリ効率が良いケースが多い