Alıntı (zafer):
> 2.stringin karakter adedini öğrenmek için std.utf kütüphanesindeki count metodunu kullanmak gerekir.
O da ne yazık ki O(N) bir işlem olduğu için biraz yavaştır. Ama öte yandan uzunluğu merak edilen bir dizgi herhalde zaten yine başından sonuna kadar işleneceği için ve o da O(N) bir işlem olduğu için count() ek bir yavaşlık getirmiyordur. (Algoritma karmaşıklıklarında O(N)'ın herhangi katı da O(N) kabul edilir.)
O(1) bir işlem olabilmesi için her dizginin ayrıca karakter uzunluğunu da tutması gerekirdi ve o da dizgilerin uzunluğunu fazla arttırmış olurdu. Ek olarak, dizgiler artık karakter dizisi değil, onları kullanan daha üst bir tür olurlardı.
count()'ı yavaş bulan bir program dizginin uzunluğunu sabit zamanda veren kendi türünü de kullanabilir:
class BenimDizgi
{
int karakterAdedi; // <-- artık count()'a gerek yok
dchar[] karakterler;
// ...
}
Alıntı:
> 4.enforce exception fırlatır. Exception mekanizması en alt düzeyden yukarı doğru ilerler ve kurulan bir düzenek ile yakalanıp evcilleştirilebilir. assert error fırlatır ve bunun tutulması önerilmez elinizi yakabilir :)
Evet. assert() ve enforce() farkı, geç gündeme gelen ilginç bir konu. D.erhane'de de bir çok yerde işlevlerin giriş koşulları için 'in' bloklarında assert ifadelerinden yararlanılması gerektiği anlatılıyor ama her duruma uygun değildirler.
in blokları sözleşmeli programlamaya (contract programming) uygun. Ancak, sözleşmeli programlama olanakları program '-release' seçeneği ile derlendiğinde ortadan kalktıkları için, arayüz işlevleri yanlış parametre ile çağrıldıklarını aslında enforce() ile denetlemelidirler. "Arayüz işlevi" derken bir kütüphane işlevini düşünebiliriz.
Basit bir örnek olarak boş olduğunda çağrılmaması gereken bir işleve bakalım:
struct Dizi
{
int elemanAdedi;
// ...
bool boş_mu()
{
return elemanAdedi == 0;
}
void elemanSil(/* ... */)
in
{
// YANLIŞ yerdeki denetim
assert(!boş_mu(), "Boş Dizi'den eleman silinemez");
}
body
{
// ...
}
}
void main()
{
auto d = Dizi();
d.elemanSil(/* ... */);
}
Yukarıdaki programda d.elemanSil() çağrısı -release seçeneği kullanılmadığında patlar; ama -release kullanıldığında tanımsız davranışa yol açar. (in bloğuna güvenen elemanSil() kimbilir hangi bellek bölgelerine dokunmaya çalışır.)
Doğrusu, o denetimin bir enforce() ile ve işlevin içinde yapılmasıdır:
import std.exception;
// ...
void elemanSil(/* ... */)
{
enforce(!boş_mu(), "Boş Dizi'den eleman silinemez");
// ...
}
Böylece Dizi.elemanSil() güvenli bir işlev olmaya devam eder.
Eğer kütüphanenin yalnızca kendisinin çağırdığı bir iç işlevden bahsediyorsak, o zaman in bloğu kullanıp kullanmamak programcıya kalmalıdır. Bütün testlerinin tamam olduğunu düşünen programcı programı -release seçeneği ile derleyebilir. İşlevin tek çağıranı kendisi olduğu için de kullanıcılara hatalı olduklarını bildirmek zorunda değildir.
Alıntı:
> 6.replicate (http://www.d-programming-language.org/phobos/std_array.htm…) belirtilen karakterleri belirtilen uzunlukta bir diziye doldurup geri verir.
"Karakterleri" yerine "elemanları" dersek daha genel olur; çünkü her türlü dizi kullanabilir. Bu işi hevesli olarak yapar ve yeni bir dizi döndürür.
Onun uzaktan arkadaşı olan std.range.repeat ise her tür değerle işler ve o değeri tekrarlama işini tembel olarak halleder:
import std.stdio;
import std.range;
void main()
{
writeln(repeat(42, 3));
}
Tekrarlayarak bir aralık oluşturur. Burada önemli olan, sonuçtaki aralık için hiç bellek ayrılmamış olmasıdır (tembelliğin yararı):
'[42, 42, 42]'
Onlara benzeyen bir de cycle() ve take()'in birlikte kullanımı var. cycle(), hep tekrarlayarak sonsuz bir aralık oluşturur; take() ise o aralıktan belirli sayıda eleman çeker. Yine tembel olarak:
import std.stdio;
import std.range;
void main()
{
writeln(take(cycle("abc"), 5));
}
Çıktısı:
'abcab'
Not: D keşke şu söz dizimini destekleseymiş istenir ama ne yazık ki henüz öyle bir güzellik yok:
writeln(cycle("abc").take(5));
Alıntı:
> 7.Her nekadar hala dalga(tilda) "~" operatörü ile string eklemeye alışamasamda D de işler böyle.
Aslında başka dillerden alıştığımız için öyle geliyor. Çünkü toplama ile uç uca ekleme farklı anlamdadırlar.
Alıntı:
> Bence hala "+" daha güzel duruyor.
Dizgiler dizi olduklarından ve ~ ile +'nın anlamları diziler üzerinde farklı olduğundan karışıklık yaratabilirdi:
auto dizgi = [ 0, 42 ];
dizgi[] += 1;
assert(dizgi == [ 1, 43 ]);
O dizi işlemleri henüz bütün dizi türleri için gerçeklenmiş durumda değil; yeni dmd sürümlerini bekliyoruz...
Alıntı:
>
> size_t toplamUzunluk = count(soldakiler[i]) + count(sağdakiler[i]);
> ```
>
> Kodun bu satırını düzenlememe rağmen sağ taraf hizalanmadı
İstediğimi tam olarak açıklayamadım. Sağ tarafın sağ kenarının hizalanmasını istiyordum. Ama kullandığımız forum program yan yana noktaları başka anlama çektiği için doğru olarak gösteremedim bile. Nokta yerine # karakteri ile göstermeye çalışayım:
'ğ#######araba
abc####otobüs'
Alıntı:
>
> foreach (i; 0 .. soldakiler.length)
> Ayrıca buradaki length niteliğini string uzunluğu veren length ile karıştırmamak gerekir bu length dizinin uzunluğunu bildirir ve dizilerle kullanımında doğru sonuç verir sanırım?
Doğru ama string'ler de dizi oldukları için onların tanımını da UTF-8 kod birimi dizisi olarak yapınca yine de dizinin uzunluğunu veriyor. UTF-8 kod birimi ile Unicode karakteri farklı şeyler oldukları için ancak dchar dizgilerinin .length niteliğini bu amaçla kullanabiliriz.
Alıntı:
> bunu depodaki projeye kendin eklesen böylece bende "pull request" ve "merge" konularında tecrübe edinmiş
Onu yapabilmem için git bilgimi tazelemem de gerekecek. :) Onu sonraya bırakalım.
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]