Created
August 8, 2019 07:47
-
-
Save kmizu/40c238262f3196bdfe8113be4e3d16d8 to your computer and use it in GitHub Desktop.
2004/09/09の自分のWeb日記
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
以前にちょっとだけ触ってみたNiceについて調べてみる。 Niceは、Javaをベースに高階関数、マルチメソッド、パラメータ型、キーワード引数、省略可能引数、Option Typesなどの機能を追加した言語で、処理系は、Java VM用のコードを吐くコンパイラとなっている。 | |
マルチメソッド、キーワード引数などは、他の言語でもよく見かけるが、 Option Typesは、他の言語ではあまり見かけない機能だ。Option Typesとは、値としてnullを許す型で、それだけ見ると、珍しくもなんともないのだが、Niceでは面白いことに、変数の型はデフォルトでnullを代入できないのだ。例えば、以下のようなコードを書くと、sはnullを代入できない型になり、もしsにnullが代入され得るようなコードを書くと、コンパイルエラーになる。 | |
let String s = "Hello";//nullは代入できない | |
もし、nullを代入可能にしたければ、型名の頭に'?'を付けて、次のように宣言する。 | |
let ?String s = "Hello";//nullが代入可能 | |
この機能は、大変面白い機能なんじゃないかと思う。例えば、Mapにキーを与えて値を取得するとき、返って来た値がnullかどうかをチェックする必要がある場合は多いが、この機能があれば、もし仮にnullかどうかのチェックを忘れたとしても、コンパイルエラーになってくれる。 | |
しかし、このチェック機能、どこまでちゃんと働くのだろうか。それを確かめるために、以下のコードを書いて実験してみることにした。このコードでは、if文の中では、valueは絶対にnullになり得ないが、それをコンパイラが判断できるかどうか。 | |
void main(String[] args){ | |
let Map map = new HashMap(); | |
map.put("A", 0); | |
map.put("B", 1); | |
map.put("C", 2); | |
?int value = map.get("E"); | |
if(value != null || false){ | |
int value2 = value; | |
} | |
} | |
このコードをコンパイルしてみると、以下のエラーメッセージが出力された。 | |
nice.lang: parsing | |
example: parsing | |
example: typechecking | |
C:\programs\nice\.\example\option_type.nice: line 8, column 21: | |
Unused local variable value2 | |
C:\programs\nice\.\example\option_type.nice: line 8, column 21: | |
The value value cannot be assigned to value2 because it might be null. | |
To allow value2 to contain the null value, it should be declared as: | |
?nice.lang.int value2 | |
どうやら、論理式の中身までは見ておらず、nullかどうかを判断する式(value != null)と他の式が、||でつながれているかどうかだけを見ているようだ。となると、&&の場合はどうなるだろうか。以下のコードも、先ほどと同じくif文の中ではvalueはnullになり得ないが、先ほどと違って、演算子の種類(&&か||か)だけを見ればそれを判断可能になっている。 | |
void main(String[] args){ | |
let Map map = new HashMap(); | |
map.put("A", 0); | |
map.put("B", 1); | |
map.put("C", 2); | |
?int value = map.get("E"); | |
if(value != null && false){ | |
int value2 = value; | |
} | |
} | |
このコードをコンパイルすると、今度は、何もエラーが出ずにコンパイルを通った。やはり、演算子の種類を見て判断しているようだ。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment