特徴的な演算子

基本的な演算子の挙動は他言語と同じなので,ここでは特徴的な演算子や,他言語と異なる注意すべき演算子について解説する.

文字列の結合

文字列の結合には<>という演算子を用いる

iex> "hello" <> " " <> "world"
"hello world"
iex> hello <> " world"  # 変数とも結合できる(helloにはあらかじめ"hello"が束縛されている)
"hello world"

文字列の結合自体は,式を埋め込む形でも行える

iex> hello = "hello"
"hello"
iex> "#{hello} world"
"hello world"

#{}の中身は評価されて表示されるので,こんなことも可能

iex> he = "he"
"he"
iex> llo = "llo"
"llo"
iex> "#{he <> llo} world"
"hello world"

マッチ演算子(=

Elixirでは=は代入の意味を持ちません.演算子の両辺を比較(パターンマッチ)するマッチ演算子と呼ばれます.

  • マッチできない組み合わせでマッチ演算子を用いると「代入が出来ない」ではなく「マッチエラー」というエラーが出力されます.
  • マップの比較をするとき,左辺に存在しないkeyは無視して比較が行われます(逆のパターンはマッチエラーとなります)
iex> 1 = 1
1
iex> 1 = 2
** (MatchError) no match of right hand side value: 2
iex> %{a: 1} = %{a: 1, b: 2} 
%{a: 1, b: 2}
iex> %{a: 1, b: 2} = %{a: 1}
** (MatchError) no match of right hand side value: %{a: 1}

変数に値を格納したいときに書く処理は他言語と変わりません.そのかわり,式の解釈が変わります.

iex> x = 3  # 変数xに3という値が「束縛(bind)」された
3

マップのマッチ

「代入」ではなく「束縛」なので,リストやマップから値を取り出すときにとても柔軟な書き方が可能になります.(超大事.私が他言語に戻れなくなった理由です)

iex> %{a: a, b: b} = %{a: 1, b: 2, c: 3}
%{a: 1, b: 2, c: 3}
iex> a
1
iex> b
2
iex> %{x: %{y: y}} = %{x: %{y: 1}}  # 入れ子構造でもOK!
%{x: %{y: 1}}
iex> y
1

リストのマッチ

リストのマッチも同様に複数の要素をマッチすることが出来ます.

iex> [a, b] = [1, 2]
[1, 2]
iex> a
1
iex> b
2

その他,リストは特殊な書き方でマッチすることが出来ます.

iex> [head | tail] = [1, 2, 3, 4, 5]  # 先頭とそれ以外を分離したい
[1, 2, 3, 4, 5]
iex> head
1
iex> tail
[2, 3, 4, 5]

|はそれ以降とを分けるための記法なので,少しトリッキーなことも出来ます.

iex> [head1, head2 | tail] = [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
iex> head1
1
iex> head2
2
iex> tail
[3, 4, 5]

不要な値を無視する

マップでは必要なkeyのみ取り出せば良いですが,リストでは順序が大事なので,使わない要素もマッチさせる必要があります.

  • 使わない変数に束縛して放置すると言う方法も採れますが,エレガントではありません(warningが出ますし,可読性も下がってしまいます)
  • このようなケースではアンダースコア_を用います
iex> [a, _, c] = [1, 2, 3]  # 1番目と3番目の要素だけ欲しい
iex> [a, 2, c] = [1, 2, 3]  # 2番目を無視できる(束縛せずに取り出せる)が,2番目の要素が未知の場合使えない

練習問題

  1. パターンマッチ1行でやってみましょう

    1. 3を変数xに拘束

       %{a: 1, b: 2, c: 3}
      
    2. :aを変数x2.3を変数yに拘束(1"a"は何にも拘束しない)

       [1, :a, "a", 2.3]
      
    3. 2を変数x4を変数y5~10のリストをzに拘束(13は何にも拘束しない)

       [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      
    4. 1を変数x4を変数yに拘束

       %{a: %{b: 1, c: 2, d: [3, 4, 5]}}
      
    5. 2を変数x[](空の配列)をyに拘束

       [1, 2, 3]
      
  2. 指定されたパターンにのみで課題が解けるパターンマッチ1行を作ってみましょう(それ以外のパターンではMatchErrorとなれば正解です)

    1. 最初のパターンのみで3を変数xに拘束(他の要素は拘束しない)

      • [1, 3, 2]
      • [1, 2]
      • [1, 3, 1]
    2. 最初のパターンのみで3を変数xに拘束(12は拘束しない._を使った無視もしてはいけない)

      • %{"a" => 1, "b" => 2, "c" => 3}
      • %{"a" => 1, "b" => 2}
      • %{:a => 1, :b => 2, :c => 3}
      • %{a: 1, b: 2, c: 3}
    3. 最初と上から2つめのパターンで3を変数xに拘束(他の要素は拘束しない)

      • [1, 2, 3, 4, 5]
      • [1, 2, 3, 4]
      • [1, 2, 3]

results matching ""

    No results matching ""