Bu, şimdiye kadar benimsediğim ilkelerime ters bir karar. Düzeltmek gerek. Burada bahsettiklerimi enum bölümünde de düzelttim ama daha siteye koymadım. Aşağıda dilimlerden bahsediyorum ama aynı durum eşleme tabloları için de geçerli.
Derleme zamanında bilinen değerleri olabildiğince enum olarak tanımlamayı öneriyordum ve öyle kullanıyordum. Kafamda şöyle canlanıyordu: enum olan sabit değerden derleme zamanında bir adet kurulur ve o değişkenin geçtiği yerlerde o sabit değer kullanılır. Bu fikir yanlışmış. Gerçekte C makrolarına daha yakın bir kullanım varmış: o enum değişkenin geçtiği yere, tanımlanan değeri sanki metin gibi yapıştırılıyor!
Önce int ile bir örnek:
import std.stdio;
void main()
{
enum i = 42;
writeln(i);
foo(i);
}
void foo(int i)
{
writefln("foo %s ile çağrıldı", i);
}
Bekleneceği gibi, yukarıdaki kod i yerine 42 yazmakla aynı sonucu verir:
writeln(42);
foo(42);
Her iki kodun çıktısı aynıdır:
'42
foo 42 ile çağrıldı
'
Şimdi de bir diziyle deneyelim:
import std.stdio;
void main()
{
enum d = [ 42, 43 ];
writeln(d.ptr);
foo(d);
}
void foo(int[] d)
{
writefln("foo %s ile çağrıldı", d.ptr);
}
Bu sefer elemanları değil, adreslerini yazdırıyorum:
'2B9CC4E25FD0
foo 2B9CC4E25FC0 ile çağrıldı
'
Gördüğünüz gibi, main içinde kullanılan 'd' ile foo()'ya gönderilen 'd' aynı değiller! Her ikisi için farklı dizi oluşturulmuş çünkü ilk elemanlarının adresi farklı.
Bunun C makrolarına benzediğini başka bir kodla gösterebiliriz. Sanki oluştur() her 'dilim' kullanımı için tekrar tekrar çağrılıyor:
import std.stdio;
int[] oluştur()
{
return [ 1, 2 ];
}
void main()
{
enum dilim = oluştur();
writeln(dilim.ptr);
writeln(dilim.ptr);
}
Çıktısı:
'2AFC5FF7CFD0
2AFC5FF7CFC0
'
Her iki writeln'a aynı değişken gönderildiği halde yine elemanları farklı. Yani, sanki yukarıdaki kodun eşdeğeri aslında şu:
writeln(oluştur().ptr);
writeln(oluştur().ptr);
O yüzden dilim veya eşleme tabloları için değerleri derleme zamanında biliniyor bile olsa enum yerine immutable kullanmak isteyebilirsiniz. Son kodu öyle değiştiriyorum:
import std.stdio;
int[] oluştur()
{
return [ 1, 2 ];
}
void main()
{
immutable dilim = oluştur().idup;
writeln(dilim.ptr);
writeln(dilim.ptr);
}
Not: Dönüş değeri ile değişken uyuşsun diye .idup'u çağırmak zorunda kaldım.
Şimdi dilim'den yalnızca bir adet var, elemanlar baştan kuruldukları yerdeler:
'2B05F3129FC0
2B05F3129FC0
'
İlgisiz not: .idup kullanmak yerine işlev 'pure' da yapılabilirdi. O zaman dönüş değeri otomatik olarak immutable'a dönüşüyor (bunu da yeni öğrendim, kitaba ekleyeceğim, ve hatta şu makaleyi de Türkçeleştireceğim: http://klickverbot.at/blog/2012/05/purity-in-d/ ). Yani şu program da çalışır:
import std.stdio;
int[] oluştur() pure // <-- pure var
{
return [ 1, 2 ];
}
void main()
{
immutable dilim = oluştur(); // <-- .idup'a gerek yok
writeln(dilim.ptr);
writeln(dilim.ptr);
}
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]