JavaScriptを有効にしてください

【Elixir】ガード節について

 ·  ☕ 4 分で読めます

【Elixir】ガード節について

Elixirは柔軟で強力なパターンマッチング機能を持ち、その一環としてガード節(guard clause)を利用することで、さらに詳細な条件でのマッチングが可能になります。Elixirのガード節について、基本的な使い方から具体的な例、使用できる関数と演算子についてのメモ。

ガード節とは?

ガード節は、関数のパターンマッチングに追加の条件を設定するためのものです。これにより、特定の条件を満たす場合にのみ関数が呼び出されるようになります。ガード節は、whenキーワードを用いて定義されます。

基本的な使い方

以下は、ガード節を使用した基本的な関数定義の例です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

defmodule GuardExample do
  # 数値が整数かつ0以上100以下の場合にマッチする関数
  def check_number(n) when is_integer(n) and n >= 0 and n <= 100 do
    "The number is an integer between 0 and 100."
  end

  # 数値が負の整数の場合にマッチする関数
  def check_number(n) when is_integer(n) and n < 0 do
    "The number is a negative integer."
  end

  # 数値が浮動小数点数の場合にマッチする関数
  def check_number(n) when is_float(n) do
    "The number is a float."
  end

  # その他の入力(数値でない場合)にマッチする関数
  def check_number(_n) do
    "The input is not a number."
  end
end

# 実行例
IO.puts GuardExample.check_number(50)
# 出力: "The number is an integer between 0 and 100."

IO.puts GuardExample.check_number(-10)
# 出力: "The number is a negative integer."

IO.puts GuardExample.check_number(3.14)
# 出力: "The number is a float."

IO.puts GuardExample.check_number("abc")
# 出力: "The input is not a number."

ガード節の例

リストの長さをチェックする関数

リストの長さをチェックする例です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
defmodule ListChecker do
  # リストが指定された長さの場合にマッチする関数
  def check_list_length(list, len) when is_list(list) and length(list) == len do
    "The list has the specified length."
  end

  # リストが指定された長さでない場合にマッチする関数
  def check_list_length(list, _len) when is_list(list) do
    "The list does not have the specified length."
  end

  # その他の入力(リストでない場合)にマッチする関数
  def check_list_length(_list, _len) do
    "The input is not a list."
  end
end

# 実行例
IO.puts ListChecker.check_list_length([1, 2, 3], 3)
# 出力: "The list has the specified length."

IO.puts ListChecker.check_list_length([1, 2, 3], 2)
# 出力: "The list does not have the specified length."

IO.puts ListChecker.check_list_length("abc", 3)
# 出力: "The input is not a list."

文字列の長さをチェックする関数

文字列が特定の長さ以上であるかをチェックする関数を作成します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
defmodule StringChecker do
  # 文字列が指定された長さ以上の場合にマッチする関数
  def check_string_length(str, len) when is_binary(str) and byte_size(str) >= len do
    "The string has the specified length or more."
  end

  # 文字列が指定された長さ未満の場合にマッチする関数
  def check_string_length(str, len) when is_binary(str) and byte_size(str) < len do
    "The string does not have the specified length."
  end

  # その他の入力(文字列でない場合)にマッチする関数
  def check_string_length(_str, _len) do
    "The input is not a string."
  end
end

# 実行例
IO.puts StringChecker.check_string_length("hello", 3)
# 出力: "The string has the specified length or more."

IO.puts StringChecker.check_string_length("hi", 3)
# 出力: "The string does not have the specified length."

IO.puts StringChecker.check_string_length(123, 3)
# 出力: "The input is not a string."

ガード節で使用できる関数まとめ

以下はガード節で使用できる関数を簡単にまとめた表です。

厳密には Elixir のKernelのものなら使用できるようです。

操作内容チェック内容使用する関数/演算子
チェックアトムis_atom/1when is_atom(var)
バイナリis_binary/1when is_binary(var)
ビットストリングis_bitstring/1when is_bitstring(var)
ブール値is_boolean/1when is_boolean(var)
浮動小数点数is_float/1when is_float(var)
関数is_function/1, is_function/2when is_function(var)
整数is_integer/1when is_integer(var)
リストis_list/1when is_list(var)
マップis_map/1when is_map(var)
数値is_number/1when is_number(var)
プロセスIDis_pid/1when is_pid(var)
ポートis_port/1when is_port(var)
リファレンスis_reference/1when is_reference(var)
タプルis_tuple/1when is_tuple(var)
数値の比較同値・大小比較==, !=, ===, !==, <, <=, >, >=when var > 0
論理演算論理条件and, or, notwhen var > 0 and var < 100
算術演算算術演算+, -, *, /, div/2, rem/2when rem(var, 2) == 0
その他のチェックリストの長さlength/1when length(list) == 3
バイト数byte_size/1when byte_size(str) >= len
マップのサイズmap_size/1when map_size(map) > 2
タプルのサイズtuple_size/1when tuple_size(tuple) == 2
先頭要素の取得hd/1when hd(list) == 1
末尾要素の取得tl/1when tl(list) == [2, 3]

&&, ||、 そして ! 使用できないとのこと。

まとめ

Elixirのガード節は、関数のパターンマッチングをさらに強化し、特定の条件を満たす場合にのみ関数を呼び出すことを可能にします。ガード節で使用できる関数や演算子には制限がありますが、これらを適切に活用することで、効率的かつ柔軟なコードを書くことができます。

参考

共有

こぴぺたん
著者
こぴぺたん
Copy & Paste Engineer