Alıntı (zafer):
> Benim anladığım kadarıyla diğer dillerde bulunan ve her türlü veriyi taşıyabilen Object türünün bir benzeri
Variant, discriminated union denen yapının bir uygulamasıdır. Ben daha önce C++'ta boost::any türüyle kullanmıştım. En basit olarak, bir union'dan ve belirli bir anda o union'ın üyelerinden hangisinin kullanılmakta olduğunu bilen bir enum'dan oluşur. (Bir kaç gün önce öğrendiğim nan-boxing yöntemi enum'a gerek bırakmıyor. Bunun hakkında da yazmak istiyorum ama zaman bulunca... :) )
Variant'ın gerçekleştirmesi kabaca şunun gibidir (burada kolaya kaçarak TypeInfo kullandım; küçük bir enum kullanıldığında daha az yer tutabilir):
import std.format;
import std.exception;
struct HerTür
{
union
{
int i;
double d;
}
TypeInfo tür;
void yaz(T)(T veri)
{
static if (is (T == int)) {
i = veri;
} else static if (is (T == double)) {
d = veri;
}
tür = typeid(T);
}
T oku(T)()
{
if (typeid(T) != tür) {
throw new Exception(format("%s türündeki veri %s olarak okunamaz"));
}
static if (is (T == int)) {
return i;
} else static if (is (T == double)) {
return d;
}
}
}
void main()
{
HerTür ht;
ht.yaz(42);
assert(ht.oku!int() == 42);
// Aynı değişkene başka tür yerleştiriyoruz:
ht.yaz(1.5);
assert(ht.oku!double() == 1.5);
// Yanlış tür olarak okumaya çalıştığımızda hata atılır:
assertThrown(ht.oku!int);
}
Variant'a bakarken Algebraic'e de bakmak gerek. Yanılmıyorsam daha kullanışlı bir tür...
Alıntı:
> , denemek ve tanımak istedim. Aşağıda küçük bir örnek var bir yapıyı (struct) Variant bir değişkene aktardım ancak kendi türünde bir değişkene geri aktaramıyorum?
> Klavye t = cast(Klavye)v;
> ```
>
Herhalde güvenli olsun diye 'DÜZELTME:'~~otomatik~~ elle yapılan dönüşümü engellemiş olmalılar. Variant'ın 'peek' işlevine hangi tür istediğimizi söylemek gerekiyor. Gösterge döndürdüğünden de * işleci:
Klavye t = *v.peek!Klavye;
Neyse ki == işlecinde otomatik tür dönüşümü var. Şu işliyor:
assert(v == q);
Ali
--
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]