Thread overview
Static Struct
Apr 26, 2022
Salih Dincer
Apr 26, 2022
Salih Dincer
Apr 26, 2022
Ali Çehreli
April 26, 2022

Merhaba,

Kısa kısa geçelim...

Bugün, 26 Nisan 2022 tarihinde 05:02:01 UTC, Ali Çehreli mealen demiş ki:

>

İç içe yapılar, içerdikleri bağlam için ek bir işaretçi taşır. Bağlama ihtiyaç duymadıklarında onları 'statik' ile tanımlarız.

Örneğin şöyle:

void main()
{
  static struct Sar { // statik yapı
    string s;

    string toString() {
      return s;
    }
  }

  // Veriye ve taşıyıcıya erişim:
  auto veri = "beşikibir".chunks(3);
       veri.map!(c => c.to!string)
           .map!(a => Sar(a)).array.writeln;
  // [beş, iki, bir]

  /* auto hataVerir = veri.map!(c => c.to!string)
                        .map!Sar;//*/
  // Hatası: cannot access frame pointer of `source.main.Sar`
}

Eğer statik olmasaydı da hata vermeyecekti! Çünkü biz 2. map() içinde lambda kullandık. Ama main() dışında her ikisi için de hata vermiyor:

struct Bar { // normal yapı
  string s;

  string toString() {
    return s;
  }
}

void main()
{
  /* Dikkat bunlar main() dışındaki
     statik olmayan Bar()'ı kullanır:      */
  auto veri = "beşikibir".chunks(3);
       veri.map!(c => c.to!string)
           .map!(a => Bar(a)).array.writeln;

  veri.map!(c => c.to!string)
      .map!Bar.array.writeln;

  // BONUS: Bu da derlenir:
  veri.array
      .map!(c => Bar(c.to!string)).writeln;
} /* ÇIKTISI: 3x
     [beş, iki, bir]
   */

Çünkü nesne adreslerine bakarsanız biri heap'de, diğeri stack'de barındırılır.

Özetle main() içinde statik kullanmak istemiyorsanız ne yapıp edin lambda kullanmaktan vaz geçmeyin. Ne kadar basit ve pratik görünürse görünsün. Yoksa bir sürü hatalar ile uğraşıyorsunuz.

Sevgiler, saygılar...

April 26, 2022

Son olarak, sınıflar referans türü olduğu için static struct yerine aşağıdaki sınıf ve daha çok olanak ile türden bağımsız taşıyıcı bir yapı gerçekleştirmek mümkünmüş:

void main() {
  class Bar(T) {
    T s;

    import std.conv : to;
    this(R)(R result) {
      this.s = result.to!T;
    }

    override string toString() {
      return s.to!string;
    }
  }

  auto Range = "beşikibir".chunks(3);
  auto strAr = [ "beş", "iki", "bir"];
  auto numAr = [ 5, 2, 1 ];
  auto funAr = [ function() => 5, function() => 2, function() => 1 ];

  auto test1 = Range.map!(a => new Bar!string(a))
                    .array;
         test1.writeln(": ",
  typeof(test1[0].s).stringof);

  auto test2 = strAr.map!(a => new Bar!string(a))
                    .array;
         test2.writeln(": ",
  typeof(test2[0].s).stringof);

  auto test3 = numAr.map!(a => new Bar!int(a))
                    .array;
         test3.writeln(": ",
  typeof(test3[0].s).stringof);

  alias func = int function();
  auto test4 = funAr.map!(a => new Bar!func(a))
                    .array;
  test4.each!((fun) => writef("%s ", fun.s()));
  ": ".writeln(typeof(test4[0].s).stringof);

} /* ÇIKTISI:
[beş, iki, bir]: string
[beş, iki, bir]: string
[5, 2, 1]: int
5 2 1 : int function()
*/
April 26, 2022
On 4/26/22 04:11, Salih Dincer wrote:
> Son olarak, sınıflar referans türü olduğu için static struct yerine
> aşağıdaki sınıf ve daha çok olanak ile türden bağımsız taşıyıcı bir yapı
> gerçekleştirmek mümkünmüş:

Tamam, gösterdiğin kod derleniyor ve çalışıyor. Ama zaten 'struct' için de ve 'static struct' için de çalışır. (?)

Not: Doğal olarak, struct kullanınca 'override' hata verir ve toString() çağrılmaz ama toString()'in çağrılmamasının bu konuyla ilgisi yok ve kod düzeltilebilir.

Ali