D.ershane Çözümleri Ddili.org

İşleç Yükleme Çözümleri

  1. Daha önce yazdığımız GününSaati.opCmp şöyleydi:
  2.     int opCmp(const ref GününSaati sağdaki) const
        {
            return (saat == sağdaki.saat
                    ? dakika - sağdaki.dakika
                    : saat - sağdaki.saat);
        }
    

    Soldaki nesnenin (işlevin üzerinde çağrıldığı nesnenin) sıralamada daha önce olması için eksi bir değer döndürülmesi gerektiğini hatırlayın. Bu nesnenin zamanda sonra olduğunda eksi bir değer üretmesi için çıkarma işlemlerinin ters sırada yapılmaları gerekir:

        int opCmp(const ref GününSaati sağdaki) const
        {
            return (saat == sağdaki.saat
                    ? sağdaki.dakika - dakika
                    : sağdaki.saat - saat);
        }
    

    Dersteki programda bu işlevi kullandığımızda çıktının büyükten küçüğe doğru (zaman içinde sonradan önceye doğru) olduğunu görüyoruz:

    [22:33,19:54,19:50,17:01,13:11,13:03,07:46,07:12,01:11,00:42]
    
  3. ZamanAralığı için <<= ve >>= işleçlerinin yazımı sırasında GününSaati'nin bazı işleçlerinden yararlanabiliriz. Onları ve toString işlevlerini de göstererek:
  4. import std.stdio;
    import std.string;
    
    struct Süre
    {
        int dakika;
    }
    
    struct GününSaati
    {
        int saat;
        int dakika;
    
        void opOpAssign(string işleç)(in Süre süre)
            if (işleç == "+")
        {
            dakika += süre.dakika;
    
            saat += dakika / 60;
            dakika %= 60;
            saat %= 24;
        }
    
        void opOpAssign(string işleç)(in Süre süre)
            if (işleç == "-")
        {
            int azalanDakika = süre.dakika % 60;
            int azalanSaat = süre.dakika / 60;
    
            dakika -= azalanDakika;
    
            if (dakika < 0) {
                dakika += 60;
                ++azalanSaat;
            }
    
            saat -= azalanSaat;
    
            if (saat < 0) {
                saat = 24 - (-saat % 24);
            }
        }
    
        string toString()
        {
            return format("%02s:%02s", saat, dakika);
        }
    }
    
    struct ZamanAralığı
    {
        GününSaati baş;
        GününSaati son;    // aralığın dışında kabul edilir
    
        void opOpAssign(string işleç)(in Süre süre)
            if (işleç == ">>")
        {
            baş += süre;
            son += süre;
        }
    
        void opOpAssign(string işleç)(in Süre süre)
            if (işleç == "<<")
        {
            baş -= süre;
            son -= süre;
        }
    
        string toString()
        {
            return format("%s-%s", baş, son);
        }
    }
    
    void main()
    {
        auto aralık = ZamanAralığı(GününSaati(14, 30),
                                   GününSaati(15, 30));
        writeln("Başlangıçta    : ", aralık);
    
        aralık >>= Süre(10);
        assert(aralık == ZamanAralığı(GününSaati(14, 40),
                                      GününSaati(15, 40)));
        writeln("Sağa öteleyince: ", aralık);
    
        aralık <<= Süre(1);
        assert(aralık == ZamanAralığı(GününSaati(14, 39),
                                      GününSaati(15, 39)));
        writeln("Sola öteleyince: ", aralık);
    }
    

    Çıktısı:

    Başlangıçta    : 14:30-15:30
    Sağa öteleyince: 14:40-15:40
    Sola öteleyince: 14:39-15:39
    
  5. ~ işlecini ZamanAralığı'nın her iki taraftaki kullanımı için tanımlamak için opBinary!"~" ve opBinaryRight!"~" üye işlevlerinin ayrı olarak tanımlanmaları gerekir.
  6. opBinaryRight!"~", ZamanAralığı'nın sağda kullanıldığı durum içindir.

    struct GününSaati
    {
        int saat;
        int dakika;
    }
    
    struct ZamanAralığı
    {
        GününSaati baş;
        GününSaati son;    // aralığın dışında kabul edilir
    
        ZamanAralığı opBinary(string işleç)
                                    (const ref GününSaati yeniSon)
            if (işleç == "~")
        {
            return ZamanAralığı(baş, yeniSon);
        }
    
        ZamanAralığı opBinaryRight(string işleç)
                                    (const ref GününSaati yeniBaş)
            if (işleç == "~")
        {
            return ZamanAralığı(yeniBaş, son);
        }
    }
    
    void main()
    {
        auto aralık = ZamanAralığı(GününSaati(1, 23),
                                   GününSaati(4, 56));
    
        auto yeniAralık = aralık ~ GününSaati(7, 0);
        assert(yeniAralık == ZamanAralığı(GününSaati(1, 23),
                                          GününSaati(7, 0)));
    
        yeniAralık = GününSaati(0, 30) ~ aralık;
        assert(yeniAralık == ZamanAralığı(GününSaati(0, 30),
                                          GününSaati(4, 56)));
    }