著作一覧 |
do { String buff = bufferedReader.readLine(); if (buff != null) { doSomething(buff); } } while (buff != null);これはもちろんコンパイルできない。
for (int i = 0; i < len; i++) { doSomething(i); }iのスコープは、for節全体となり、for()の中で宣言したものが{}内でも有効で、そこを外れると参照できなくなる。
while ((String buff = br.readLine()) != null) { doSomething(buff); }どうも、try-catch-finally節といい、Javaのスコープルールは無意味に固い(コンパイラを簡単に実装できるようにしたのだろうか? でも、それは今となっては大した問題ではなかろうし、forの特別扱いが気持ち悪い)。
ジェズイットを見習え |
C++を引きずったからなんでしょうね。そもそもなぜC++は、Cから拡張する時に(この時は0から考えることができたはず)、こういうスコープルールにしたんでしょうね。
C++については、Cfrontが最初にあるから、制御構造まで手が回らなかったのだと思いますが、Javaについてはユースケース分析が甘かったんだろうなと。
もう式とか文とか分けなけりゃいいのに。
それと、変数の可視性は別のような。
Cでは関数の頭でしかローカル変数を定義できなかったのを、C++で大幅に緩和しているので、この程度の文法変更はやろうと思えば簡単にできたと思うんですよね。しかもC++って、このあたりのスコープを途中で変更までしてますよね(たしかforの中の変数のスコープを一度変更していたはず)。その時にwhileの方も変更することは、やろうと思えば造作も無かったんじゃないかと。たぶんwhileで書けることは、forでも書けるんで「変数定義したければ、for使えばいいんじゃね?」って感じなのでしょうね。
条件式の中で宣言できたとしても、宣言「文」だったら<br> while (String buff = br.readLine(); buff != null)<br>などと分けなけりゃいけないわけで、これのどこがforと違うのかという話になるのでは。<br>それよりも<br>* 制御文の中で定義された変数のスコープはその文の終わりまで<br>* 宣言式の値は最後の初期化値<br>としてやればforでもwhileでもifでもswitchでもOKになったんではないかと。
なるほど。宣言が文か式か、か。確かにそうですね。>中田さん<br>ああ、後から結構変えてましたね。> るいもさん<br>で、僕はむしろ、BufferdReaderが駄目なAPIだと思います。readLineメソッドを定義して、なぜIteratoreを返すメソッドを入れなかったのかと。
Iteratorを使えないのは、例のチェック例外の呪いのせいかと。next()やhasNext()はIOExceptionを投げられないんで。
ちょっと長くなるので、続きは、7/1のほうで。