null değeri ve is işleci
Bir önceki derste referans türünden olan değişkenlerin hiçbir nesneye erişim sağlamadan da oluşturulabileceklerini söylemiştim:
File erişimSağlayan = new File("mektup"); File dosya; // erişim sağlamayan
Bir referans türü olduğu için yukarıdaki dosya'nın bir kimliği vardır; ama erişim sağladığı bir işletim sistemi dosyası henüz yoktur. Böyle bir değişkenin bellekte şu şekilde durduğunu düşünebiliriz:
dosya
---+-----+---
| o |
---+--|--+---
▼
?
Not: Yukarıdaki soru işaretinin yerinde aslında null olması gerekiyor; aşağıda gösteriyorum.
Böyle bir değişken kendisine bir nesne atanana kadar kullanılamaz bir durumdadır. Doğal olarak, erişim sağladığı bir File nesnesi olmadığı için o dosya ile işlemler yapmamız beklenemez:
File dosya;
dosya.writefln("merhaba");
O işlem programın çökmesine neden olur:
$ ./deneme
Segmentation fault
"Segmentation fault", programın geçerli olmayan bir bellek bölgesine erişmeye çalıştığı için işletim sistemi tarafından acil olarak sonlandırıldığını gösterir.
Hatta dosya'nın başka bir değişkene eşit olup olmadığını bile denetlemek yasal değildir:
File geçerliDosya = new File("deneme"); File dosya; if (dosya == geçerliDosya) { // ... }
Program o durumda da çöker:
$ ./deneme
Segmentation fault
dosya ve geçerliDosya'nın eşitlik karşılaştırmaları, erişim sağladıkları nesneler düzeyinde yapılır; asıl nesnelerin eşit olup olmadıklarına bakılır. Geçerli bir nesnesi olmadığı için dosya ile böyle bir işlem de yapılamaz.
null değeri
Erişim sağladığı nesne henüz belli olmayan referans türü değişkenleri null özel değerine sahiptir. Bu değeri de herhangi başka bir değer gibi yazdırabiliriz:
dout.writefln(null);
Bu değer, diğer bütün dillerde olduğu gibi, D'de de 0 özel değerini taşır. Yukarıdaki satırın çıktısı:
0000
Değeri null olan bir değişken çok kısıtlı sayıda işlemde kullanılabilir:
- Erişim sağlaması için geçerli bir nesne atamak
nullolup olmadığını denetlemek
dosya = new File("muzik_listesi", FileMode.In);
O atamadan sonra artık dosya'nın erişim sağladığı bir nesne vardır. Bu atamadan sonra, dosya artık bütün File işlemleri için kullanılabilir.
if (dosya == null) // ← derleme HATASI
Ne yazık ki, == işleci asıl nesneleri karşılaştırdığı için; ve bir null değişkenin eriştirdiği geçerli bir nesne bulunmadığı için, o ifade derlenemez.
Bu yüzden, bir değişkenin null olup olmadığını denetlemek için is işleci kullanılır.
is işleci
is, İngilizce'de "olmak" fiilinin "öyledir" kullanımındaki anlamına sahiptir. Bu dersi ilgilendiren kullanımında ikili bir işleçtir, yani sol ve sağ tarafına iki değer alır. Bu iki değer aynıysa true, değilse false üretir.
Not: is'in örneğin şablon olanağında tekli işleç olarak kullanıldığı durumlar da vardır.
İki değerden birisinin null olabildiği durumlarda == işlecinin kullanılamadığını gördük. Onun yerine is'i kullanmak gerekir. "Bu değişken null ise" koşulunu denetlemeye yarar:
if (dosya is null) { // hiçbir nesneye erişim sağlamıyor }
is, başka türlerle de kullanılabilir. Örneğin iki tamsayı değişkenin değerleri şöyle karşılaştırılabilir:
if (hız is yeniHız) { // ikisi aynı değerde } else { // ikisi farklı değerde }
Dilimlerde de iki dilimin aynı elemanlara erişim sağlayıp sağlamadıklarını denetler:
if (dilim is dilim2) { // aynı elemanları paylaşıyorlar }
!is işleci
== ve != işleçlerine benzer şekilde, is'in tersi !is işlecidir. Değerler eşit olmadığında true üretir:
if (hız !is yeniHız) { // farklı değerlere sahipler }
null değer atamak
Referans türlerinin kendi değerleri olmadığını ve başka bir değere erişim sağladıklarını biliyoruz. Böyle bir değişkene null değerini atamak, o değişkenin artık hiçbir değere erişim sağlamamasına neden olur.
Eğer bu atama sonucunda asıl değere erişen başka referans değişkeni kalmamışsa, asıl değer çöp toplayıcı tarafından sonlandırılacaktır. Hiçbir referans tarafından erişilmiyor olması, o değerin artık kullanılmadığını gösterir.
Örnek olarak, önceki dersteki iki değişkenin tek bir değere eriştiği duruma bakalım:
auto dosya = new File("oyuncu_listesi", FileMode.Out); auto dosya2 = dosya;
(isimsiz File nesnesi) dosya dosya2
---+-------------------+--- ---+---+--- ---+---+---
| ... | | o | | o |
---+-------------------+--- ---+-|-+--- ---+-|-+--
▲ | |
| | |
+--------------------+------------+
Bu değişkenlerden birisine null atamak, onun bu değerle ilişkisini keser:
dosya = null;
File nesnesine artık yalnızca dosya2 tarafından erişilmektedir:
(isimsiz File nesnesi) dosya dosya2
---+-------------------+--- ---+---+--- ---+---+---
| ... | | o | | o |
---+-------------------+--- ---+-|-+--- ---+-|-+--
▲ ▼ |
| null |
| |
+---------------------------------+
İsimsiz File nesnesine erişen son referans olan dosya2'ye de null atanması, asıl nesnenin sonlanmasına neden olur:
dosya2 = null;
Çöp toplayıcı asıl nesneyi türüne göre ya hemen, ya da ilerideki bir zamanda sonlandıracaktır. Program açısından artık o nesne yoktur çünkü o nesneye erişen referans kalmamıştır:
dosya dosya2
---+-------------------+--- ---+---+--- ---+---+---
| | | o | | o |
---+-------------------+--- ---+-|-+--- ---+-|-+--
▼ ▼
null null
Eşleme tabloları dersinin birinci problemi, bir eşleme tablosunu boşaltan üç yöntem gösteriyordu. Şimdi o yöntemlere bir dördüncüsünü ekleyebiliriz; eşleme tablosu değişkenine null değer atamak, değişkenin erişim sağladığı asıl tablo ile ilişkisini keser:
string[int] isimleSayılar; // ... isimleSayılar = null; // artık hiçbir elemana erişim // sağlamaz
Yukarıdaki File örneğine benzer şekilde, eğer isimleSayılar asıl tabloya erişim sağlayan son referans idiyse, asıl tablonun elemanları çöp toplayıcı tarafından sonlandırılacaklardır.
Bir dilimin de artık hiçbir elemana erişim sağlaması istenmiyorsa null atanabilir:
int[] dilim = dizi[ 10 .. 20 ]; // ... dilim = null; // artık hiçbir elemana erişim sağlamaz
Özet
null, hiçbir değere erişim sağlamayan referans değeridirnullreferanslar yalnızca iki işlemde kullanılabilirler: değer atamak,nullolup olmadığını denetlemek==işleci asıl nesneye erişmek zorunda olduğu için,nullreferanslarisile denetlenmelidiris'in tersi!is'dirnullatanan referans artık hiçbir elemana erişim sağlamaz- Hiçbir referansın erişim sağlamadığı nesneler çöp toplayıcı tarafından sonlandırılırlar
D.ershane
Forum
Wiki
Projeler
Tanıtım
İletişim
Hakları