Bu konuyu daha önce de çok konuştukmuştuk: D'nin dinamik dizileri başka dillerdekilere benzemiyor. d.D grubunda "Passing dynamic arrays" diye bir konu açılınca hatırlamak için bir program daha yazdım.
Aşağıdaki programda "dinamik dizi" yerine "dilim" diyorum çünkü aslında ikisi de aynı şey: kendilerine ait elemanları bulunmayan, yalnızca o elemanlara erişim sağlayan olanaklar.
D'nin dilimlerinin garip tarafı, aynı elemanlara erişim sağlayan birden fazla dilim bulunduğunda ortaya çıkabiliyor: dilimlerden birisinin uzunluğu arttığında artık aynı elemanlara erişim sağlamaz hale geliyorlar. Uzunluk artınca elemanlar kopyalanıyor ve uzunluğu artan dilim bu yeni elemanlara erişim sağlamaya başlıyor. Dilimler o zamana kadar aynı elemanlara erişim sağlıyorlarken, uzunluğun artmasından sonra artık farklı elemanlara erişim sağlıyorlar.
Programı -unittest seçeneği ile derlemek gerekiyor...
void uzunluğunu_değiştirmeden(int[] dilim)
{
/*
* 'dilim', işleve gönderilen dilimle aynı elemanlara erişim
* sağlamaktadır. Elemanlarda burada yapılan değişiklikler asıl dizideki
* elemanları da etkiler.
*/
dilim[0] = 0;
dilim[1] = 1;
assert(dilim == [ 0, 1, 9 ]);
}
unittest
{
int[] d = [ 9, 9, 9 ];
uzunluğunu_değiştirmeden(d);
assert(d == [ 0, 1, 9 ]);
}
void uzat(int[] dilim)
{
/*
* Dilimin uzunluğu artana kadar asıl elemanlara erişim sağlanmaktadır; bu
* değişiklik, asıl dizinin elemanını da değiştirir
*/
dilim[0] = 0;
/*
* 'dilim'in uzunluğunun arttırılması; onun artık asıl elemanlara değil, o
* elemanların kopyalarına erişim sağlamasına neden olur.
*/
++dilim.length; // <-- Bu işlem sonucunda bütün elemanlar KOPYALANIRLAR
/* O yüzden bu; artık asıl diziyi değil, yalnızca bu yerel dilimi
* etkiler */
dilim[1] = 1;
/* Asıl dizide bulunmayan bir elemanı değiştiriyoruz */
dilim[3] = 3;
assert(dilim == [ 0, 1, 9, 3 ]);
}
unittest
{
int[] d = [ 9, 9, 9 ];
uzat(d);
assert(d == [ 0, 9, 9 ]);
}
void eleman_ekle(int[] dilim)
{
/*
* Bu da uzat() işlevindeki gibidir; eleman eklenene kadar asıl dizideki
* elemanlar; eklendikten sonra ise yerel kopyalar değişir
*/
dilim[0] = 0;
dilim ~= 3; // <-- Bu işlem sonucunda bütün elemanlar KOPYALANIRLAR
dilim[1] = 1;
assert(dilim == [ 0, 1, 9, 3 ]);
}
unittest
{
int[] d = [ 9, 9, 9 ];
eleman_ekle(d);
assert(d == [ 0, 9, 9 ]);
}
void kısalt(int[] dilim)
{
/*
* Diğer işlevlerde olduğu gibi, şimdilik asıl dizideki elemanı değiştirir
*/
dilim[0] = 0;
/*
* 'dilim'in uzunluğunda yapılan değişiklik, onun daha az sayıda elemana
* erişim sağlamasına neden olur. Ama hâlâ asıl dilimdeki elemanlara
* erişim sağlamaktadır.
*/
--dilim.length;
/* O yüzden bu, asıl diziyi de etkiler */
dilim[1] = 1;
assert(dilim == [ 0, 1 ]);
}
unittest
{
int[] d = [ 9, 9, 9 ];
kısalt(d);
assert(d == [ 0, 1, 9 ]);
}
void ref_parametre_olarak(ref int[] dilim)
{
/* Parametre listesinde 'ref' olarak belirtildiği için, bu işlevdeki
* 'dilim', asıl dizinin takma ismi gibi işlemektedir. Burada yapılan
* değişiklikler doğrudan asıl diziyi etkiler. */
dilim[0] = 0;
++dilim.length;
dilim[1] = 1;
dilim[3] = 3;
dilim ~= 4;
assert(dilim == [ 0, 1, 9, 3, 4 ]);
}
unittest
{
int[] d = [ 9, 9, 9 ];
ref_parametre_olarak(d);
assert(d == [ 0, 1, 9, 3, 4 ]);
}
void main()
{}
Akılda tutmakta yarar var. :)
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]
Permalink
Reply