null値とis演算子
前の章で、参照型の変数は特定のオブジェクトを参照する必要はないことを学んだ。
参照型である上記のvariableには識別子があるが、まだどのオブジェクトも参照していない。このようなオブジェクトは、次の図のようにメモリ内の場所にあると想像することができる。
variable
───┬──────┬───
│ null │
───┴──────┴───
値を参照しない参照は、nullである。これについては、以下で詳しく説明する。
このような変数はほぼ無用の状態である。参照するMyClassオブジェクトが存在しないため、実際のMyClassオブジェクトが必要な文脈では使用できない:
use()が受け取るパラメーターが参照するオブジェクトが存在しないため、存在しないオブジェクトのメンバにアクセスしようとすると、プログラムがクラッシュする:
"セグメンテーションフォールト"は、不正なメモリアドレスにアクセスしようとしたために、オペレーティングシステムによってプログラムが終了したことを示している。
nullの値
特別な値nullは、他の値と同じように表示できる。
出力:
null
null変数は、次の2つの文脈でのみ使用できる:
- オブジェクトを代入する
上記の代入により、
variableは新しく構築されたオブジェクトへのアクセスを提供する。この時点から、variableは、MyClass型の有効な操作に使用できる。 nullであるかどうかを判断する。ただし、
==演算子は比較する実際のオブジェクトを必要とするため、以下の式はコンパイルできない。そのため、変数が
nullであるかどうかは、is演算子によって決定する必要がある。
is演算子
この演算子は、"null値を持つか"という質問に答える。
isは、他の型の変数にも使用できる。以下の使用例では、2つの整数のvaluesを比較している。
スライスと組み合わせて使用すると、2つのスライスが同じ要素のセットを参照しているかどうかを判断する:
!is演算子
!isは、isの逆である。値が異なる場合、trueを返す。
nullの値の代入
nullの値を参照型変数に代入すると、その変数は現在のオブジェクトへの参照を停止する。
その代入が実際のオブジェクトへの最後の参照を終了させる場合、実際のオブジェクトはガベージコレクタによる最終化の対象となる。結局、どの変数からも参照されていないオブジェクトは、プログラム内で使用されていないことになる。
前の章で、2つの変数が同じオブジェクトを参照していた例を見てみよう。
以下の図は、そのコードを実行した後のメモリの状態を表している:
(anonymous MyClass object) variable variable2
───┬───────────────────┬─── ───┬───┬─── ───┬───┬───
│ ... │ │ o │ │ o │
───┴───────────────────┴─── ───┴─│─┴─── ───┴─│─┴───
▲ │ │
│ │ │
└────────────────────┴────────────┘
nullの値をこれらの変数の1つに代入すると、その変数とオブジェクトとの関係が切断される。
この時点では、MyClassオブジェクトを参照しているのはvariable2だけになる:
(anonymous MyClass object) variable variable2
───┬───────────────────┬─── ───┬────┬─── ───┬───┬───
│ ... │ │null│ │ o │
───┴───────────────────┴─── ───┴────┴─── ───┴─│─┴───
▲ │
│ │
└──────────────────────────────────┘
最後の参照にnullを代入すると、MyClassオブジェクトが到達不能になる:
このような到達不能なオブジェクトは、将来のどこかの時点でガベージコレクタによって破棄される。プログラムの観点からは、オブジェクトは存在しないことになる:
variable variable2
───┬───────────────────┬─── ───┬────┬─── ───┬────┬───
│ │ │null│ │null│
───┴───────────────────┴─── ───┴────┴─── ───┴────┴──
関連配列の章の演習セクションで、関連配列を空にする方法について議論した。現在、4つ目の方法を知っている:nullを関連配列変数に代入すると、その変数と要素の関係が切断される:
MyClassの例と同様に、namesが連想配列の要素への最後の参照であった場合、それらの要素はガベージコレクタによって最終化される。
スライスにもnullを代入できる:
要約
nullは、変数がどの値にもアクセスできないことを示す値である。null値を持つ参照は、2つの操作(値への代入と、nullであるかどうかの判定)でのみ使用できる。==演算子は実際のオブジェクトにアクセスする必要があるため、変数がnullであるかどうかを判断するには、is演算子を使用する必要がある!isは、is- 変数に
nullを代入すると、その変数は何も参照しなくなる - 変数によって参照されていないオブジェクトは、ガベージコレクタによって破棄される