Dizilerin gelişimleri durdu ve karışıklıkları çözüldü. (Bunları 2.045 ile aşağıda deniyorum.)
Aklıma gelen iki tanesi:
- sabit uzunluklu dizilerin değer türü kabul edilmelerini biz de yaşadık (bu konuyu D.ershane'de değiştirmiştim bile)
Bu, C'den ve C++'dan çok büyük bir fark olarak kabul edilmeli. O dillerde, diziler yarım referans gibi türlerdir. İşlevlere gönderilirken özel kuralları filan vardır.
D'de olay iyice çözülmüş durumda: sabit uzunluklu diziler kopyalanır, dinamik diziler (aslında dilim ile aynı şey) ise referans türüdür; kopyalanmaz:
// Sabit uzunluklu dizi olduğu için, parametre kopyalanır
void sabitAlan(int[3] dizi)
{
// yalnızca yerel 'dizi' değişir
dizi[2] = 22222;
}
// Dilim olduğu için, parametre kopyalanmaz
void dilimAlan(int[] dizi)
{
// gönderilen asıl dizi değişir
dizi[2] = 22222;
}
void main()
{
int[3] sabitUzunluklu = [ 0, 1, 2 ];
sabitAlan(sabitUzunluklu);
// değişmemiş; çünkü kopyalanarak gönderilir
assert(sabitUzunluklu == [ 0, 1, 2 ]);
int[] dilim = [ 0, 1, 2 ];
dilimAlan(dilim);
// değişmiş; çünkü referans olarak gönderilir
assert(dilim == [ 0, 1, 22222 ]);
// Sabit uzunluklu olan da dilim olarak gönderilebilir
dilimAlan(sabitUzunluklu);
assert(sabitUzunluklu == [ 0, 1, 22222] );
}
- Dilimlere eklemek, şaşırtıcı sonuçlar doğurabilir:
void main()
{
// İki tane elemanı olan bir dilim oluşturuyoruz
int[] dilim;
dilim ~= 3;
dilim ~= 33;
// İçinde 3 ve 33 bulunmasını bekleriz
assert( dilim == [ 3, 33 ]);
// Başka bir dilimi, bu dilim ile ilkliyoruz
int[] başka_dilim = dilim;
// Bu noktadan sonra iki dilimin elemanları da aynıdır
// (aslında "aynı elemanlara erişim sağlarlar" demek daha
// doğru)
assert( dilim == [ 3, 33 ]);
assert(başka_dilim == [ 3, 33 ]);
// Buradaki 'is' işleci, "aynı elemanlara erişim sağlar"
// anlamına geliyor
assert(dilim is başka_dilim);
// Göstergeler dersinde gördüğümüz .ptr değerleri de aynı
assert(dilim.ptr == başka_dilim.ptr);
// Birinci dilimde bir değer değiştiriyoruz
dilim[0] = 7;
// Evet, ikisinin de ilk elemanları değişmiştir
assert( dilim == [ 7, 33 ]);
assert(başka_dilim == [ 7, 33 ]);
// Diğer ilişkilerinde bir değişme beklemeyiz; aynılar
assert(dilim is başka_dilim);
assert(dilim.ptr == başka_dilim.ptr);
// Dilimlerden birisine bir eleman ekliyoruz
dilim ~= 333;
// O dilimin yeni bir elemanı oluyor
assert( dilim == [ 7, 33, 333 ]);
// Diğer dilimin bu konuyla bir ilgisi yok
assert(başka_dilim == [ 7, 33 ]);
// Artık "aynı elemanlara erişim sağlar" diyemeyiz; o
// yüzden, !is işleci doğru oluyor
assert(dilim !is başka_dilim);
// İşin garibi, erişim sağladıkları elemanlar yine de
// "aynı", çünkü .ptr değerleri aynı
assert(dilim.ptr == başka_dilim.ptr);
// Yine değer değiştiriyoruz
dilim[0] = 8;
// O değişikliği ikisinde de görüyoruz
assert( dilim == [ 8, 33, 333 ]);
assert(başka_dilim == [ 8, 33 ]);
// İşler bu noktadan sonra ilginçleşiyor
//
// Önce, bu aşamada belleğin nasıl olduğuna
// bakalım. Ortalıkta yalnızca 3 tane eleman var. dilim,
// bunların üçüne de erişim sağlıyor; başka_dilim ise ilk
// ikisine:
//
// ... | 8 | 33 | 333 | ...
// \ \ \
// -------------- dilim
// \ \
// ---------- başka_dilim
// Şimdi, "diğer" dilime eleman ekliyoruz
başka_dilim ~= 3333;
// O son işlem, bu iki dilimin arasındaki "paylaşma"
// ilişkisini sona erdirir. Bunun nedeni, ikinci dilimin
// sonunda serbestçe eleman ekleyeceği yer
// bulunmamasıdır. Çünkü orada birinci elemanın eklemiş
// olduğu 333 vardır.
//
// Önemli nokta: O son işlem, başka_dilim'in elemanlarının
// yeni bir yere kopyalanmalarına ve başka_dilim'in artık
// farklı elemanlara erişim sağlamasına neden olur:
//
// ... | 8 | 33 | 333 | ...
// \ \ \
// -------------- dilim
//
//
// ... | 8 | 33 | 3333 | ...
// \ \ \
// ------------- başka_dilim
// Evet, içerikler beklediğimiz gibi:
assert( dilim == [ 8, 33, 333 ]);
assert(başka_dilim == [ 8, 33, 3333]);
// Artık farklı elemanlara erişim sağlıyorlar (yani !is)
assert(dilim !is başka_dilim);
// Kopyalandıklarını da .ptr değerlerinin farklı
// olmasından anlıyoruz
assert(dilim.ptr != başka_dilim.ptr);
}
Çok uzun bir hikaye oldu. :)
Aslında hiç de zor bir konu değil ama dilimlerin belirli bir noktadan sonra birbirlerinden bağımsız hale gelebileceklerini anlamamız gerekiyor.
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]