D.ershane D Programlama Dili Dersleri

çökme: [crash], programın hata ile sonlanması
çöp toplayıcı: [garbage collector], işi biten nesneleri sonlandıran düzenek
değer türü: [value type], değer taşıyan tür
dilim: [slice], başka bir dizinin bir bölümüne erişim sağlayan yapı
eşleme tablosu: [associative array], elemanlarına tamsayı olmayan indekslerle de erişilebilen veri yapısı (bir 'hash table' gerçekleştirmesi)
nesne: [object], belirli bir sınıf veya yapı türünden olan değişken
referans türü: [reference type], başka bir nesneye erişim sağlayan tür
şablon: [template], derleyicinin örneğin 'türden bağımsız programlama' için kod üretme düzeneği
... bütün sözlük

Bölümler
İngilizce Kaynaklar
Diğer



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:

    BirSınıf erişimSağlayan = new BirSınıf;

    BirSınıf değişken;  // erişim sağlamayan

Bir referans türü olduğu için yukarıdaki değişken'in bir kimliği vardır; ama erişim sağladığı bir nesne henüz yoktur. Böyle bir değişkenin bellekte şu şekilde durduğunu düşünebiliriz:

      değişken
   ---+------+---
      | null |
   ---+------+---

Hiçbir nesneye erişim sağlamayan referansların değerleri null'dır. Bunu aşağıda anlatıyorum.

Böyle bir değişken kendisine bir nesne atanana kadar kullanılamaz bir durumdadır. Doğal olarak, erişim sağladığı bir BirSınıf nesnesi olmadığı için o değişken ile işlemler yapmamız beklenemez:

void kullan(BirSınıf değişken)
{
    writeln(değişken.üye);
}

void main()
{
    BirSınıf değişken;
    kullan(değişken);
}

kullan işlevine verilen değişken hiçbir nesneye erişim sağlamadığı için, olmayan nesnenin üye'sine erişilmeye çalışılması 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.

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:

    writeln(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ı:

0

Değeri null olan bir değişken çok kısıtlı sayıda işlemde kullanılabilir:

  1. Erişim sağlaması için geçerli bir nesne atamak
  2.     değişken = new BirSınıf;  // artık nesnesi var
    

    O atamadan sonra artık değişken'in erişim sağladığı bir nesne vardır. değişken artık BirSınıf işlemleri için kullanılabilir.

  3. null olup olmadığını denetlemek
  4.     if (değişken == null)     // ← derleme HATASI
    

    Ne yazık ki, == işleci asıl nesneleri karşılaştırdığı için; ve null bir 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ı yukarıda gördük. Onun yerine is'i kullanmak gerekir. "Bu değişken null ise" koşulunu denetlemeye yarar:

    if (değişken 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ürleri erişim sağladıkları nesnelere sahip değildirler; yalnızca o nesnelere erişim sağlarlar. Böyle bir değişkene null değerini atamak, o değişkenin artık hiçbir nesneye erişim sağlamamasına neden olur.

Eğer bu atama sonucunda asıl nesneye erişen başka referans değişkeni kalmamışsa, asıl nesne çöp toplayıcı tarafından sonlandırılacaktır. Hiçbir referans tarafından erişilmiyor olması, o nesnenin artık kullanılmadığını gösterir.

Örnek olarak, önceki dersteki iki değişkenin tek bir nesneye eriştikleri duruma bakalım:

    auto değişken = new BirSınıf;
    auto değişken2 = değişken;
  (isimsiz BirSınıf nesnesi)    değişken    değişken2
 ---+-------------------+---  ---+---+---  ---+---+---
    |        ...        |        | o |        | o |
 ---+-------------------+---  ---+-|-+---  ---+-|-+--
              ▲                    |            |
              |                    |            |
              +--------------------+------------+

Bu değişkenlerden birisine null atamak, onun bu değerle ilişkisini keser:

    değişken = null;

BirSınıf nesnesine artık yalnızca değişken2 tarafından erişilmektedir:

  (isimsiz BirSınıf nesnesi)    değişken     değişken2
 ---+-------------------+---  ---+----+---  ---+---+---
    |        ...        |        |null|        | o |
 ---+-------------------+---  ---+----+---  ---+-|-+--
              ▲                                  |
              |                                  |
              +----------------------------------+

İsimsiz BirSınıf nesnesine erişen son referans olan değişken2'ye de null atanması, asıl nesnenin sonlanmasına neden olur:

    değişken2 = 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:

                                değişken      değişken2
 ---+-------------------+---  ---+----+---  ---+----+---
    |                   |        |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 BirSınıf ö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