Thread overview
Parametre Serbestliği dersi ve.dup ihtiyacı
Dec 05, 2012
Salih Dinçer
Dec 05, 2012
Salih Dinçer
December 05, 2012

Merhaba,

Dersi (http://ddili.org/ders/d/parametre_serbestligi.html) daha iyi anlamak için, Ali hocanın şurada (http://ddili.org/forum/post/8322) naklettiği gerekliliği (.dup ihtiyacı) kendi örneğim ile irdelemeye karar verdim. Gerçi çok daha basit bir örnek mevcut olmalı ama gerçekten karmaşık bir veri geçişi olmasını istedim. Bu sayede Renkli Noktalar örneğini sürdümüş olacağız. Zaten orada bahsedilen sorunu (vagon gibi dizilen nesneler ile verileri Poligon lokomotifine takarak bir seferde sunma) karıştırmadan aşağıdaki gibi iki yapı ile halledebileceğimizi düşünüyorum...

struct Nokta {
 uint x, y;

 union Rengi {
   uint cCode;       // RGB+a composite code
   ubyte r, g, b, a; // a = alpha channel value
 } Rengi rengi;

 this(uint sütun, uint satır, uint renk) {
   x = sütun;
   y = satır;
   rengi.cCode = renk;
 }

 string toString() const {
   uint xRGB = rengi.cCode >> 8;
   real oran = cast(real)rengi.a;
        oran /= 2.55;
   return format("X = %s, Y = %s noktasının rengi\n"
                 "#%X, şeffaflık: %%%.0f", x, y,
                  xRGB, oran);
 }
}

struct Noktalar {
 Nokta[] noktalar;

 this(Nokta[] veriler...) {
   noktalar = veriler;//.dup;
 }
}

import std.stdio, std.string;

void main() {
 auto ayarlar = Noktalar (Nokta(320, 240, 0xA0A0A0A0),
                          Nokta(640, 480, 0xB0B0B0B0),
                          Nokta(960, 720, 0xC0C0C0C0));

 foreach(nokta; ayarlar.noktalar) nokta.writeln;
}

Çıktısı:
'X = 320, Y = 240 noktasının rengi
#A0A0A0, şeffaflık: %63
X = 640, Y = 480 noktasının rengi
#B0B0B0, şeffaflık: %69
X = 960, Y = 720 noktasının rengi
#C0C0C0, şeffaflık: %75
'
Gördüldüğü gibi nesneleri, köşeli parantez kullanılmadan olduğu gibi aktarıp tekrar nesnenin üyesine doğrudan erişerek ekrana yazıyorum. Ancak .dup kullanmasam da aynı sonucu alıyorum. Acaba örneği daha karmaşıklaştırmamız mı gerekiyor?

Teşekkürler...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 05, 2012

İlginçmiş...

Gerçekten de bir .dup ile sorun çözülüyor. Bu ister struct içinde, isterseniz return ile dönerken (tabi dönen diziyse) yapın işe yarıyor. Olayı basitleştirince de sorunu görüyorsunuz:

import std.stdio;

struct Foo {
 int[] i;

 this(int[] n...) {
   i = n;//.dup;
 }
}

auto bar(int[] x...) {
 auto foo = Foo(3, 2, 1);

 return foo.i;//.dup;
}

void main() {
   bar(1, 2, 3).writeln;
}

Çıktısı:
'[10, 3, -1076643896]
'
Normalde verdiğimiz değerlere (1, 2, 3) rağmen 3, 2, 1 çıktısını almamız gerekiyordu. Ama hemen yukarıda görüldüğü gibi her bilgisayarda farklı çıkabilecek bir değer dönüyor. Hata iletisi yok ama sonuç hatalı.

Dilerseniz 3, 2, 1 yerine x yazabilirsiniz. O sırada tıpkı parametreleri köşeli paranteze alıp isimsiz dizi göndermemiz gibi bir şey oluyor. Çünkü işleve gönderdiğimiz parametrelerin bir dizi halinde kopyaları alınıyor.

İlginç, başka bir şey demiyorum...:)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 05, 2012

Geçici olduğunu söylediğimiz otomatik dizi senin deneyinde main()'in içindeyken geçerli oluyor. (Aslında o bile garanti olmamalı.) Bütün işlemleri bir işlev içine aktarınca main içinde yazdırılan dizinin bozuk olduğunu gözlemliyorum:

Noktalar foo()
{
   auto ayarlar = Noktalar (Nokta(320, 240, 0xA0A0A0A0),
                            Nokta(640, 480, 0xB0B0B0B0),
                            Nokta(960, 720, 0xC0C0C0C0));

   foreach(nokta; ayarlar.noktalar) nokta.writeln;

   return ayarlar;
}

void main() {
   writeln(foo());
}

Çıktısı:

'X = 320, Y = 240 noktasının rengi
#A0A0A0, şeffaflık: %63
X = 640, Y = 480 noktasının rengi
#B0B0B0, şeffaflık: %69
X = 960, Y = 720 noktasının rengi
#C0C0C0, şeffaflık: %75
Noktalar([X = 374921088, Y = 48 noktasının rengi
#1658D7, şeffaflık: %50, X = 48, Y = 4294967295 noktasının rengi
#0, şeffaflık: %0, X = 960, Y = 720 noktasının rengi
#0, şeffaflık: %1])
'

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]