条件式にはbool型を使って欲しい

ifなどの条件式としては、bool値を評価させた方が分かりやすい。

すごくシンプルなif文がある。

if(0 < 1){
   Print("実行される");
}else{
   Print("実行されない");
}
//実行結果
実行される

比較演算が長ったらしくなる場合は、演算結果を変数に入れる事もある。
個人的にはあまりやらないが、読みやすさは問題ないと思う。

bool result = 0 < 1;
if(result){
   Print("実行される");
}else{
   Print("実行されない");
}
//実行結果
実行される

何らかの関数が処理結果としてbool値を返すケースもある。
これもifの条件式として書くのも良し、一旦変数に戻り値を受け取るも良し。
なおifの条件式として関数の戻り値が使えるという事は、その関数は実行されている。

if(foo()){
   Print("実行される");
}else{
   Print("実行されない");
}
bool foo(){
   Print("foo処理");
   return 0 < 1;
}
//実行結果
foo処理
実行される

関数がint値を返すケースが多々ある。
処理がうまくいけば正の整数、失敗していれば”-1”を返す、といった関数が沢山ある。

ifの条件式には、数値を指定することができてしまう。

if(1){
   Print("実行される");
}else{
   Print("実行されない");
}
//実行結果
実行される

実行結果を見てわかるように、”1”をifに評価させるとtrueになるようだ。
では、下記ならどうか。

if(-1){
   Print("実行される");
}else{
   Print("実行されない");
}
//実行結果
実行される

残念ならが、これもtrueになるようだ。

if(0){
   Print("実行される");
}else{
   Print("実行されない");
}
//実行結果
実行されない

これは実行されない。
では、double型ならどうなるか。

if(0.0){
   Print("0.0: 実行される");
}
if(0.1){
   Print("0.1: 実行される");
}
if(5.1){
   Print("5.1: 実行される");
}
if(-3.0){
   Print("-3.0: 実行される");
}
//実行結果
0.1: 実行される
5.1: 実行される
-3.0: 実行される

intと同様だった。
数値がifで評価できるのは、なぜだろう。
bool型へのキャストが行われるのだろうか。

例えば、

bool intNum = 1;
bool doubleNum = -2.0;
bool intZero = 0;
bool doubleZero = 0.0;

となっていてもエラーにはならない。
中身を表示すると、

//実行結果
intNum: true
doubleNum: true
intZero: false
doubleZero: false

になる。
数値がbool型に暗黙的にキャストされることが確認できる。
ただ、ifが暗黙的にbool型にキャストしているかどうかは分からない。

では、ifの条件式にstringやdatetimeは指定できるだろうか。

if("foo"){   //コンパイルエラー
   Print("foo: 実行される");
}
if(""){   //コンパイルエラー
   Print("空文字: 実行される");
}

string型はコンパイルエラーになる。
string型はboolにキャストできないだろうか。

bool str = "";   //コンパイルエラー
bool str = (bool)"";   //コンパイルエラー

できない。

if(D'2000.01.01'){
   Print("実行される");
}
//実行結果
実行される

datetimeは実行された。
数値型同様、bool型へのキャストもされる。
datetime型をbool型にキャストした際、falseになるデータはあるだろうか。

falseをdatetimeにキャストすればわかる。

datetime d = false;
Print(d);
//実行結果
1970.01.01 00:00:00

UNIXエポックが表示される。
これをまたbool型にキャストすれば、

bool b = D'1970.01.01 00:00:00';
Print(b);
//実行結果
false

falseになった。
UNIX時間は数値なので、そう考えればそうかという感じに。

次に、NULLはどうか。

if(NULL){   //コンパイルエラー
   Print("実行される");
}

NULLを条件式に指定することはできない。
NULLは”何もない”ことを表すのでそもそもデータではないが、このNULL定数をbool型にキャストできるだろうか。

bool null = NULL;
Print("null: ", null);
//実行結果
null: false

おや、できる。キャストが行われているんだろうか。
明示的にキャストしてみよう。

bool null = (bool)NULL;
Print("null: ", null);
//実行結果
null: false

これも大丈夫。
ということは、

if(!(bool)NULL){
   Print("実行される");
}
//実行結果
実行される

これはコンパイルエラーにはならない。

NULLは、すべての基本型の変数に代入が可能だ。その際キャストの必要は無い。
NULLが代入された変数には初期値が入る。例えばint型の変数にNULLを代入すれば中身は”0”、bool型の変数なら”false”になる。

しかし条件式がNULL自体を評価することはできないらしい。

という事で、とりあえず条件式に指定できるのはbool型だけでない事はわかった。
でも、わかりづらいので、やめよう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

コメントする