第7章 判断を下す
この章の目的
この章を終えるころには、複数の可能性の中から選択するプログラムを書けるようになります。
問いを立てる、比較
判断は問いから始まり、プログラムにおける問いとは比較です。比較の結果は bool、すなわち true か false のいずれかになります。keleusma repl でプロンプトを開き、いくつか試してみてください。
> 3 < 5
true
> 7 == 7
true
比較演算子は < より小さい、> より大きい、<= 以下、>= 以上、== 等しい、!= 等しくない、です。2つの値が等しいかどうかを問うには二重の == を用いることに注意してください。単一の = はすでに名前を束縛するために使われているためです。
問いを組み合わせる、and、or、not
問いは組み合わせられます。Keleusma は組み合わせの語を記号ではなく単語として書きます。他の多くの言語がここで記号を用いるため、その習慣が誤って持ち込まれがちですので、今のうちに記憶に定着させておく価値があります。
andは両辺が真であるときに真になります。orは少なくとも一方の辺が真であるときに真になります。xorは両辺が異なるときに真になります。notは真と偽を反転させます。
> (3 < 5) and (7 == 7)
true
> not (3 < 5)
false
Keleusma には && も || もありません。用いる単語は and、or、xor、not です。
これら4つは両辺を評価します。さらに2つの単語 andalso と orelse は、それらの短絡形です。andalso は左辺が false になった時点で右辺を見ずに false を生成し、orelse は左辺が true になった時点で右辺を見ずに true を生成します。右辺が左辺の検査後にのみ意味を持つ場合にこれらを用い、日常的な場面では and と or を用いてください。
ビットを扱う
上記の単語は bool 全体に作用します。それらのビットレベルの仲間は、Word または Byte のすべてのビットに一度に作用します。band、bor、bxor は2つの値をビットごとに組み合わせ、bnot は1つの値のすべてのビットを反転させます。
> 12 band 10
8
> 12 bor 10
14
> 12 bxor 10
6
4つのシフトは、値のビットを指定した数だけ左または右に移動させ、そのアセンブリニーモニックにちなんで名付けられています。lsl と asl は左にシフトします。lsr は0で埋めながら右にシフトする符号なし形式であり、asr は符号ビットをコピーしながら右にシフトする符号付き形式です。シフト数は定数でも実行時の値でも構いません。
> 1 lsl 4
16
> 48 lsr 2
12
これらの演算子はここでは Word と Byte に作用し、第23章の多倍長 Multiword<N, F> 型にも作用します。この型も同じ名前を持ちます。
値を選ぶ、if と else
if 式は問いに基づいて2つの値のいずれかを選びます。
fn louder_of(a: Word, b: Word) -> Word {
if a > b { a } else { b }
}
fn main() -> Word {
louder_of(80, 100)
}
実行してください。出力は 100 です。この関数は2つの音の強さ、すなわち2つの音量の尺度を比較し、大きい方を返します。a > b が真であれば if は a を生成し、そうでなければ b を生成します。if 全体が1つの値であり、その値こそが louder_of が返すものです。
多数の中から選ぶ、match
可能性が2つより多い場合、match は1つの値を一連のケースと照合します。
fn third_quality(semitones: Word) -> Word {
match semitones {
3 => 1,
4 => 2,
_ => 0,
}
}
fn main() -> Word {
third_quality(4)
}
実行してください。出力は 2 です。三和音の性質を定める音程はその3度です。3半音の3度は短3度で、ここでは 1 と書きます。4半音の3度は長3度で、2 と書きます。アンダースコア _ はすべてを受け止めるケースであり、それより上に列挙されていないものすべてに合致し、0 を生成します。
すべての match はあらゆる可能性を網羅しなければなりません。_ のケースがそれを保証します。第13章では match を再び詳しく扱います。
前提を確認する、assert
bool の問いは、開発中に前提を守る役割も果たせます。assert 文は条件を検査し、それが偽である場合、アサーション失敗としてプログラムを停止させます。
assert count > 0;
assert index < length, "index past the end of the buffer";
assert はデバッグ補助であり、意図的な規則に従います。この検査は keleusma compile --debug で生成されるデバッグビルドにおいてのみ存在します。通常のビルドはアサーションを完全にコンパイル時に除去するため、出荷されるプログラムでは何のコストもかかりません。したがってデバッグビルドと通常のビルドは、1つの成果物ではなく別々のコンパイルであり、任意のメッセージは keleusma strip で取り除ける除去可能なデバッグ情報として記録されます。開発中に真であると信じることを表明するには assert を用い、出荷されるプログラムで保持されなければならない検査には型システムと第23章の部分演算構文に頼ってください。
assert は予約語ではありません。式の前に書けばアサーション文となり、assert(...) と書けば、たまたま assert という名前を付けた関数への通常の呼び出しとなります。
この章のまとめ
- 比較(
<、>、<=、>=、==、!=)はboolを生成します。 - 問いは記号ではなく
and、or、xor、notという単語で組み合わせます。andalsoとorelseは短絡形です。 - ビットレベルの演算子は
WordまたはByteのすべてのビットに作用します。band、bor、bxor、bnot、およびシフトlsl、asl、lsr、asrです。 if condition { ... } else { ... }は2つの値のいずれかを選びます。matchは多数のケースの中から選び、_はすべてを受け止めるケースです。assert conditionは開発時の前提を検査します。これは--debugビルドにおいてのみ存在し、それ以外ではコンパイル時に除去されます。
次章では、ある動作を固定回数繰り返します。