トップ «前の日記(2010-06-29) 最新 次の日記(2010-07-01)» 編集

日々の破片

著作一覧

2010-06-30

_ Javaのスコープの素朴な疑問

ある人が書いた本の中のサンプルコードに次のようなものがあった。
do {
    String buff = bufferedReader.readLine();
    if (buff != null) {
        doSomething(buff);
     }
} while (buff != null);
これはもちろんコンパイルできない。
String buffの可視性は{}の中で閉じているからだ。
でも、次のは違う。
for (int i = 0; i < len; i++) {
    doSomething(i);
}
iのスコープは、for節全体となり、for()の中で宣言したものが{}内でも有効で、そこを外れると参照できなくなる。
この、あるステートメントを構成する()内で変数を宣言できるというのをwhile系にも適用すればよかったのだ。
while ((String buff = br.readLine()) != null) {
    doSomething(buff);
}
どうも、try-catch-finally節といい、Javaのスコープルールは無意味に固い(コンパイラを簡単に実装できるようにしたのだろうか? でも、それは今となっては大した問題ではなかろうし、forの特別扱いが気持ち悪い)。
本日のツッコミ(全9件) [ツッコミを入れる]
_ るいも (2010-07-01 09:22)

C++を引きずったからなんでしょうね。そもそもなぜC++は、Cから拡張する時に(この時は0から考えることができたはず)、こういうスコープルールにしたんでしょうね。

_ arton (2010-07-01 09:40)

C++については、Cfrontが最初にあるから、制御構造まで手が回らなかったのだと思いますが、Javaについてはユースケース分析が甘かったんだろうなと。

_ なかだ (2010-07-01 10:17)

もう式とか文とか分けなけりゃいいのに。

_ arton (2010-07-01 10:38)

それと、変数の可視性は別のような。

_ るいも (2010-07-01 10:48)

Cでは関数の頭でしかローカル変数を定義できなかったのを、C++で大幅に緩和しているので、この程度の文法変更はやろうと思えば簡単にできたと思うんですよね。しかもC++って、このあたりのスコープを途中で変更までしてますよね(たしかforの中の変数のスコープを一度変更していたはず)。その時にwhileの方も変更することは、やろうと思えば造作も無かったんじゃないかと。たぶんwhileで書けることは、forでも書けるんで「変数定義したければ、for使えばいいんじゃね?」って感じなのでしょうね。

_ なかだ (2010-07-01 12:40)

条件式の中で宣言できたとしても、宣言「文」だったら<br> while (String buff = br.readLine(); buff != null)<br>などと分けなけりゃいけないわけで、これのどこがforと違うのかという話になるのでは。<br>それよりも<br>* 制御文の中で定義された変数のスコープはその文の終わりまで<br>* 宣言式の値は最後の初期化値<br>としてやればforでもwhileでもifでもswitchでもOKになったんではないかと。

_ arton (2010-07-01 13:23)

なるほど。宣言が文か式か、か。確かにそうですね。>中田さん<br>ああ、後から結構変えてましたね。> るいもさん<br>で、僕はむしろ、BufferdReaderが駄目なAPIだと思います。readLineメソッドを定義して、なぜIteratoreを返すメソッドを入れなかったのかと。

_ るいも (2010-07-01 17:56)

Iteratorを使えないのは、例のチェック例外の呪いのせいかと。next()やhasNext()はIOExceptionを投げられないんで。

_ arton (2010-07-01 23:01)

ちょっと長くなるので、続きは、7/1のほうで。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|12|

ジェズイットを見習え