C'de de yaşadığım önemsiz bir sıkıntı vardır: bir değişkenin bazı değerlerden birisi olup olmadığını denetlemek için aynı karşılaştırma || ile art arda tekrarlanır:
void foo(dstring gün)
{
if ((gün == "Cumartesi") ||
(gün == "Pazar")) {
writeln("Hafta sonu");
} else {
writeln("İş günü");
}
}
(Not: D'de dizgiler switch deyimlerinde de kullanılabiliyor; C'deki sıkıntıyı göstersin diye bu örneğe takılıyorum.)
Oradaki 'gün ==' karşılaştırmaları yerine hep şöyle yazabilmek istemişimdir:
if (gün == ("Cumartesi" || "Pazar")) { // <-- DERLEME HATASI
Öyle yazınca "gün, Cumartesi veya Pazar mı" demek isterim ama || bir mantıksal ifade olduğu için ve dizgiler mantıksal ifadelerde kullanılamadıkları için derlenemez.
Daha kötüsü, bazı yeni başlayanlar gerçekten öyle yazdıklarında ama tesadüfen mantıksal ifadeye dönüşebilen türler kullandıklarında, kod derlenir ve yanlış çalışır. Örneğin gün ismi yerine gün numarası kullanmış olsak:
void foo(int gün)
{
if (gün == (6 || 7)) {
writeln("Hafta sonu");
Sıfırdan farklı değerler mantıksal ifadelerde 'true' değerinde oldukları için sağdaki ifade (true || true) olur, sonucu true'dur ve o da 'gün' gibi bir int ile karşılaştırıldığında 1 değerini alır. Sonuçta da yalnızca gün numarası 1 olduğunda, yani Pazartesi olduğunda eşitlik doğru çıkar ve sonuç yanlıştır: Pazartesi için "Hafta sonu" yazılır, diğer günler için "İş günü"!
Yine konuyu fazla uzattım. :) Asıl söylemek istediğim; bunu sağlayan bir işlev, Phobos'a eklenmek üzere... Adını önce 'either' olarak önerdiler ama galiba 'any' veya 'isAny' olacak. Gerçekleştirmesinde fazla konuşmadığımız şablon çokuzlu parametreleri (template tuple parameters) geçiyor ama çok kolay kullanılıyor (İngilizce forumdan aktarıyorum):
import std.stdio;
import std.typecons;
struct Any(Ts...)
{
Tuple!Ts data_;
bool opEquals(E)(E e)
{
foreach (i, T; Ts)
{
if (data_[i] == e) return true;
}
return false;
}
}
auto any(Ts...)(Ts args)
{
return Any!Ts(tuple(args));
}
void foo(int gün)
{
if (gün == any(6, 7)) {
writeln("Hafta sonu");
} else {
writeln("İş günü");
}
}
void main()
{
foo(7);
}
Şablon çokuzlu parametrelerine şurada "Çokuzlu parametreleri" başlığı altında değinmiştim:
http://ddili.org/ders/d/sablonlar_ayrintili.html
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]
Permalink
Reply