Elixir学習記
← 前 | 目次 | 次 → |
---|---|---|
2. データ型 | 3. 演算子 | 4. パターンマッチング |
演算子
算術演算
加算 +
6 + 2 # == 8
減算 -
6 - 2 # == 4
乗算 *
6 * 2 # == 12
除算 /
6 / 2 # === 3.0 (割り切れる場合でも Float になる)
整数の除算 div
rem
# 商
div(6, 2) # == 3
# 剰余
rem(6, 2) # == 0
論理演算
-
and
,or
,not
は Guard であり、第1引数がtrue
かfalse
でないとエラーになる -
&&
,||
,!
は Function であり、どんなデータ型でもOK-
false
,nil
のみ偽と判定される
-
Guard、Functionという違いについて教えていただきました -> @zacky1972さんのコメント
論理積 and
&&
true and false # == false
1 && nil # == nil
-
and
- 第1引数が
false
なら第1引数(false
)を返す - 第1引数が
true
なら第2引数を返す
- 第1引数が
-
&&
- 第1引数が
false
かnil
なら第1引数(false
かnil
)を返す - 第1引数がそれ以外なら第2引数を返す
- 第1引数が
論理和 or
||
false or true # == true
nil || 1 # == 1
-
or
- 第1引数が
false
なら第2引数を返す - 第1引数が
true
なら第1引数(true
)を返す
- 第1引数が
-
||
- 第1引数が
false
かnil
なら第2引数を返す - 第1引数がそれ以外なら、第1引数を返す
- 第1引数が
否定 not
!
not true # == false
!1 # == false
-
not
-
true
ならfalse
を返す -
false
ならtrue
を返す
-
-
!
-
false
かnil
ならtrue
を返す - それ以外なら
false
を返す
-
比較演算
equal (等しい) ==
===
# 緩い比較(型が違っても同じ値と見做される)
1 == 1 # true
1 == 2 # false
1 == 1.0 # true
# 厳密な比較(型が違う=異なる値と見做される)
1 === 1 # true
1 === 1.0 # false
not equal (等しくない) !=
!==
# 緩い比較
1 != 1 # false
1 != 2 # true
1 != 1.0 # false
# 厳密な比較
1 !== 1 # false
1 !== 2 # true
1 !== 1.0 # true
greater than (より大きい) >
2 > 1 # true
2 > 2 # false
less than (より小さい) <
2 < 1 # false
2 < 2 # false
greater than or equal (以上) >=
2 >= 1 # true
2 >= 2 # true
less than or equal (以下) <=
2 <= 1 # false
2 <= 2 # true
参考: 異なる型の比較
- 型により大小関係が決まっている
- 異なる型の要素が含まれるListのソートなどで関係してくる
number < atom < reference < function < port < pid < tuple < map < list < bitstring
100 < [10] # == true
[10] < "1" # == true
ビット演算
import Bitwise
a = 12 # 0b1100
b = 10 # 0b1010
AND &&&
band/2
a &&& b
band(a, b)
# == 8 (0b1000)
# 補足
# a &&& b
# |> IO.inspect(base: :binary)
# とすればバイナリ表現を得ることができる
OR |||
bor/2
a ||| b
bor(a, b)
# == 14 (0b1110)
NOT ~~~
bnot/1
~~~a
bnot(a)
# == -13 (-0b1101)
# 12 (00...001100) の反転なら、 (11...110011) になるはずだが、そうなっていない?
# 負の整数は2の補数で表現されることが多いが、Elixirのバイナリ表示は -(マイナス)と整数部の組み合わせになっている?
# 負の整数が2の補数で表現される場合、ビット反転は a * (-1) - 1 に相当するため、その結果を再現している?
XOR bxor/2
bxor(a, b)
# == 6 (0b0110)
# ^^^ は deprecated
算術右シフト >>>
bsr/2
a >>> 1
bsr(a, 1)
# == 6 (0b110)
-4 >>> 1 # -4 == -0b100
# == -2 (-0b10)
算術左シフト <<<
bsl/2
a <<< 1
bsl(a, 1)
# == 24 (0b11000)
その他の演算子
文字列(バイナリ)連結 <>
"Hello" <> " " <> "World" # == "Hello World"
<<10>> <> <<20>> # == <<10, 20>>
リスト連結 ++
[1, 2] ++ [3, 4] # == [1, 2, 3, 4]
マッチ =
- 単なる代入演算子ではない
- 詳細はパターンマッチの記事で書く予定
x = 1
ピン ^
- 左辺の変数を値割り当てでなくパターンマッチに使うことができる
- aの値を固定しておくイメージ
a = 12 # 割り当て
a = 13 # 割り当て
^a = 13 # パターンマッチング
パイプ |>
- 左辺の結果を、右辺に指定した関数の第1引数として渡す
- 処理の流れがわかりやすく、可読性向上に役立つ
add = fn a, b -> a + b end
subtract = fn a, b -> a - b end
multiply = fn a, b -> a * b end
divide = fn a, b -> a / b end
add.(10, 5) # == 15
|> subtract.(3) # == 12
|> multiply.(2) # == 24
|> divide.(4) # == 6.0
参考:上記をパイプなしにした場合
divide.(multiply.(subtract.(add.(10, 5), 3), 2), 4)
非常に読みづらい
文字列マッチ =~
- 左辺に文字列、右辺に文字列or正規表現を取る
- 右辺が文字列の場合
- 右辺が左辺に含まれる(左辺 ⊇ 右辺)場合、
true
となる
- 右辺が左辺に含まれる(左辺 ⊇ 右辺)場合、
- 右辺が正規表現の場合
- 正規表現にマッチする場合、
true
となる
- 正規表現にマッチする場合、
"tutorialspoint" =~ "poi" # == true
"tutorialspoint" =~ "poi2" # == false
"tutorialspoint" =~ ~r/[a-z]+/ # == true
"tutorialspoint" =~ ~r/[A-Z]+/ # == false
コードポイント ?
UTF-8 コードポイントを返す
?a # == 97
?\s # == 32
キャプチャ &
無名関数定義で使う(関数の記事でまた触れる予定)
&(&1 + &2)
# fn a, b -> a + b end に相当
# == で比較すると false になったので完全に同じではないみたい
三項
三項演算子はないため、if - do - else で実現する
if true, do: "True!", else: "False!" # == "True!"
イン in
:yes in [:true, :false, :yes] # == true
参考資料
感想
- 論理演算の論理積、論理和について
- Boolean(
true
かfalse
)でなく第1引数、第2引数を返す仕様なのは面白いと思った
- Boolean(
- ビット演算について
- Integerでなく、BitString(もしくはせめてBinaries)を対象として計算できるほうが便利そうだけど、どうやるんだろう?
-> @mnishiguchiさんのコメントが参考になります!
- Integerでなく、BitString(もしくはせめてBinaries)を対象として計算できるほうが便利そうだけど、どうやるんだろう?