varの制約
varの制約
このレッスンでできるようになること。var が使える場所と使えない場所を即答できるようになります。Silver では var は「書けるか書けないか」だけを問われるので、覚える量は多くありません。
まず予測してください
次の6行のうち、コンパイルが通るのはどれでしょうか。
var a = 10;
var b;
var c = null;
var d = { 1, 2, 3 };
var e = new int[3];
var f = 1, g = 2;答えと理由
通るのは a と e の2行だけです。
var b;は初期化子が無いのでエラーです。var は右辺から型を推論するしくみなので、右辺が無いと型が決まりませんvar c = null;もエラーです。null にはどの型とも決められる性質があり、推論の材料になりませんvar d = { 1, 2, 3 };もエラーです。配列初期化子だけの書き方は、左辺に配列型が書いてあるときにしか使えません。var e = new int[3];のようにnewを付ければ通りますvar f = 1, g = 2;もエラーです。var は1行に1つの変数しか宣言できません
使える場所は「ローカル変数」だけ
var が使えるのは、メソッドの中のローカル変数、for 文の初期化部、拡張 for 文の変数、try-with-resources のリソース変数です。次はすべてコンパイルエラーになります。
public class Sample {
var field = 10; // フィールドには使えない
var method() { return 1; } // 戻り値の型には使えない
void run(var x) { } // メソッドの引数には使えない
void go() {
try { }
catch (var e) { } // catch の引数には使えない
}
}逆に、次はすべて通ります。
void go(int[] nums) {
for (var i = 0; i < nums.length; i++) { }
for (var n : nums) { }
var total = 0;
}var は予約語ではありません
ここが試験でいちばん意地悪に出る部分です。var は予約語ではなく「予約型名」という扱いなので、変数名やメソッド名としては今までどおり使えます。
int var = 10; // 通る
var var2 = var + 1; // 通る「var は予約語になったので変数名に使えない」という選択肢が並んだら、それは誤りです。ただしクラス名としては使えません。class var { } はコンパイルエラーになります。
型は推論された時点で固定されます
var n = 10; と書いた n は int に確定します。あとから n = "abc"; と入れ直すことはできません。var は動的型付けではなく、書く手間を省くだけの静的な型推論です。ここを「何でも入る箱」と読ませる選択肢もよく出ます。
また var x = 10; の x は int であって Integer ではありません。整数リテラルは int と推論され、小数リテラルは double と推論されます。var y = 1.5f; のように接尾辞を付ければ float になります。
まとめ
ローカル変数だけ、初期化子は必須、null と配列初期化子と複数宣言は不可、そして var という名前の変数は今でも作れます。この5点が出題の全体像です。
要件
- 数値・文字列・配列の3つの変数を var で宣言すること
- 配列は new を使って作ること。初期化子だけの書き方は var では通りません
- for 文の添字も var で宣言すること
- 5つの項目を半角スペース1つでつないだ文字列を返すこと
入出力例
fix() → "10 ab 3 5 3"
fix() → "10 ab 3 5 3"