LoginSignup
7
1

More than 1 year has passed since last update.

Elixir 学習記(3. 演算子)

Last updated at Posted at 2023-02-14

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引数が truefalse でないとエラーになる
  • &&, ||, ! は Function であり、どんなデータ型でもOK
    • false, nil のみ偽と判定される

Guard、Functionという違いについて教えていただきました -> @zacky1972さんのコメント

論理積 and &&

true and false # == false
1 && nil # == nil
  • and
    • 第1引数がfalseなら第1引数(false)を返す
    • 第1引数がtrueなら第2引数を返す
  • &&
    • 第1引数がfalsenilなら第1引数(falsenil)を返す
    • 第1引数がそれ以外なら第2引数を返す

論理和 or ||

false or true # == true
nil || 1 # == 1
  • or
    • 第1引数がfalseなら第2引数を返す
    • 第1引数がtrueなら第1引数(true)を返す
  • ||
    • 第1引数がfalsenilなら第2引数を返す
    • 第1引数がそれ以外なら、第1引数を返す

否定 not !

not true # == false
!1 # == false
  • not
    • trueならfalseを返す
    • falseならtrueを返す
  • !
    • falsenilなら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)

非常に読みづらい:sob:

文字列マッチ =~

  • 左辺に文字列、右辺に文字列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(truefalse)でなく第1引数、第2引数を返す仕様なのは面白いと思った
  • ビット演算について
    • Integerでなく、BitString(もしくはせめてBinaries)を対象として計算できるほうが便利そうだけど、どうやるんだろう?
      -> @mnishiguchiさんのコメントが参考になります!
7
1
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1