三項演算子のtrueの場合とfalseの場合に返す値は、同じ型の値でないとダメ
その答えはYESでもあり、NOでもあります。なぜなら言語によるからです。
世の中には多くのプログラミング言語がありますが、それぞれを二分するものの一つに静的型付けと動的型付けがあります。前者を採用する言語のほとんどは(後述するある型を持つ場合を除いて)同じ型である必要がありますが、後者を採用する言語のほとんどは同じ型である必要はありません。以下、細かく見ていきましょう。
静的型付けとは変数や関数の戻り値、式の評価値についての型が構文解析時にコンパイル時に、つまり、静的に決定されることをいいます。この型付けを採用している言語を静的型付き言語といいます。JavaScriptと名前だけが似ているJavaは静的型付き言語ですので、その例を見てみましょう。
Java
1public class Main {
2 public static void main(String[] args) throws Exception {
3 boolean flag = true;
4 int x = flag ? 1 : "hello"; // エラー
5 }
6}
Javaでは変数を何かしらの型であると宣言する必要があります。上ではint
型(32bit整数値)としましたが、"hello"
は文字列ですので、コンパイル時にエラーになります。かといってString x = flag ? 1 : "hello";
と書いても、今度は1
がString
型(文字列)ではないので、やはりエラーになります。詳しく言うと、x
がint
型であるとした時点で、flag ? 1 : "hello"
はflag
が何であっても、int
型ではなければならないということです。
大切なのは、この判断は静的に行っていると言うことです。上のプログラムを見ると三項演算子の結果が1
であることは自明ですが、それはあくまで、実行して初めてわかることであり、静的な構文解釈ではわかりません。つまり、静的に三項演算子の結果が何の型であるかと言うことが決定されなければならないとも言えます。
対して、動的型付けでは違います。こちらは逆に、変数などが実行時、つまり、動的に決定されるものです。そのため、変数に対しては定まった型というものはなく、何でも入れることができます。JavaScriptは動的型付き言語ですので、その場合の例を見ましょう。
JavaScript
1const flag = true;
2const x = flag ? 1 : "hello";
上のコードはエラーになりません。x
は数値でも文字列でも動的に決定されれば良いので、どれでも入る状態です。ですので、たとえ1
になっても"hello"
になっても問題ありません。三項演算子の結果が、状況によって型が異なっても問題にしないのが動的型付けなのです。これは、三項演算子だけでは無く、関数の戻り値などにも言えることです。
さて、静的型付き言語なら全て同じ型でなければならないのかというと、そうではありません。例えば、JavaScriptを静的型付けにしたTypeScriptでは、次のように書けます。
TypeScript
1const flag : boolean = true;
2const x : number | string = flag ? 1 : "hello";
これはコンパイルエラーにはなりません。型としては問題ないと判断されたのです。このときx
はnumber | string
という型です。これは、数値か文字列のどちらかという状態が混ざったような型になります。これをUnion型と言います。三項演算子もnumber | string
というUnion型を返すとなるため、型としては全て正しいとなるのです。Union型は比較的新しい静的型付き言語では多くで取り入れられていますが、Javaのような古い言語には存在しません。
と言うことで結論を言うと
- Union型が無い静的型付き言語ではほぼ正しい
- Union型がある静的型付き言語ではほぼ間違っている
- 動的型付き言語ではほぼ間違っている
となるとおもいます。なお、ほぼとしているのは、イレギュラーな動作する言語が存在する可能性があるからです。(プログラミング言語は非常にたくさんあるので、全てを調べ尽くすことは難しいです)
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/10/18 13:42
2017/10/18 13:45
退会済みユーザー
2017/10/18 13:47
2017/10/18 13:49