👑

Nim | 条件分岐の基本

2021/08/15に公開

条件分岐

条件分岐とは制御構文のひとつで、ある処理を条件によって切り替えることができます。
Nimにおける条件分岐はいくつかの選択肢があり、目的に応じて使い分ける必要があります。

単純な条件分岐

ifはNimの最も単純な条件分岐構文です。
bool型の値を条件として受け取り、trueの場合はifブロックのプログラムを、条件がfalseの場合はelseブロックのプログラムを実行します。
また、2つ以上の条件を記述するときはelifブロックを記述します。

if文
let number = 23

if number mod 2 == 0:
  echo "even"
elif number mod 3 == 0:
  echo "multiple of three"
else:
  echo  number
stdout
23

また、Nimには値を返すと値を返さないが存在しますが、条件分岐は文としても式としても記述できます。

if式
let number = 23

echo if number mod 2 == 0:
  number div 2
elif number mod 3 == 0:
  number div 3 + 1
else:
  (number - 1) div 2
stdout
11

if文はelseブロックを書くことは強制されませんが、if式では何らかの値を必ず返す必要があるので、書かなければいけません。

elseブロックを省略する
let number = 23

echo if number mod 23 == 0:
  "lucky number"
コンパイル時エラー
Error: expression '"lucky number"' is of type 'string' and has to be used (or discarded)

lucky numberに問題があるように見えるが、そもそもパースできていない

値を複数のパターンと比較する

caseは、値を複数のパターンと比較する強力な機能です。
序数型クラスに属する型、もしくはstringfloatのいずれかの値を受け取って、複数のパターンと比較します。
Javaなどのswitchと異なり、最初にマッチしたパターンのみを実行するため、break文などを記述する必要はありません。

case文
type fruits = enum
  orange, banana, apple, muscat, grape

let recently_eaten_fruit = muscat

case recently_eaten_fruit
of orange, muscat, grape:
  echo "My favorite flutes!"
else:
  echo "Not my favorite, but a tasty fruit."

このとき、序数型クラスに属する型の場合は全てのパターンが網羅されている必要があります。

網羅しない場合
case recently_eaten_fruit
of orange, muscat, grape:
  echo "My favorite flutes!"
コンパイルエラー
Error: not all cases are covered; missing: {banana, apple}

ifと同様に式として記述できます。式として記述する場合には、値がstring型かfloat型であったとしても全ての場合で何らかの値を返すようにしなければなりません。

case式
let n = 3.14

echo case n:
  of 3.14: "pi"
  of 2.71: "e"
  else: "unknown"

コンパイル時評価条件分岐

Nimはコンパイル時に評価される条件分岐、whenを備えています。
ifcaseは基本的には実行時に評価される[1]のですが、whenはコンパイル時に条件が評価され、条件を満たすブロックのみがコンパイルされます。
C言語の#ifdefに似た概念と言えます。

when文
when defined(windows):
  echo "windows"
elif defined(macos):
  echo "MacOS"
elif defined(linux):
  echo "Linux"
else:
  echo "unknown operation system"

OS固有のコードや環境変数に依存するプログラムを生成するために便利です。

脚注
  1. macro内に記述されたifcaseはもちろんコンパイル時に評価されます ↩︎

Discussion