我可以在D中創建類數組嗎?就像:D類中的類Array
interface A {}
class AA: A {}
class AB: A {}
class AC: A {}
ClassList!A list = new ClassList!A {AA, AB, AC};
void testf(ulong testv) {
A a = new list[testv];
}
我可以在D中創建類數組嗎?就像:D類中的類Array
interface A {}
class AA: A {}
class AB: A {}
class AC: A {}
ClassList!A list = new ClassList!A {AA, AB, AC};
void testf(ulong testv) {
A a = new list[testv];
}
是的,這是可能的,但不一定完全如何你有它。你可以創建一個類型爲元組的類型列表:
import std.typetuple;
alias list = TypeTuple!(AA, AB, AC);
但是,你不能在運行時將它索引爲一個數組;嘗試new list[n]
將是編譯時錯誤。相反,你會創建一個上循環,並返回該實例,像這樣的輔助函數:
foreach(index, type; list)
if(index == testv) {
a = new type();
break;
}
,編譯是foreach(foo; compile_time_list)
實際上變成一個大的展開循環的方式。生成的代碼,如果你寫道:
if(0 == testv) { a = new AA(); goto end; }
if(1 == testv) { a = new AB(); goto end; }
if(2 == testv) { a = new AC(); goto end; }
end:
因此與運行時的值工作,消除編譯時間列表,你想數組索引之間的差距。
值得注意的是,這不一定是最有效的,但除非你的班級名單有一千個條目,我懷疑這一點很重要。另一個提高速度的方法是在編譯時從列表中生成一個switch語句,然後將其混合。switch語句將編譯爲更高效的查找表。但賠率是簡單的循環是好的。
無論如何,把它在一起,我們得到:
import std.stdio;
interface A {}
class AA: A {}
class AB: A {}
class AC: A {}
import std.typetuple;
alias list = TypeTuple!(AA, AB, AC);
void testf(ulong testv) {
A a;
foreach(index, type; list)
if(index == testv) {
a = new type();
break;
}
if(a is null)
writeln("bad type index");
else {
writeln(typeid(cast(Object) a), " was created");
}
}
void main() {
testf(0);
testf(1);
testf(2);
testf(3);
}
結果:
$ ./test50
test50.AA was created
test50.AB was created
test50.AC was created
bad type index
正是我們想要的。
順便說一句,typeid(cast(Object) a)
可能看起來很奇怪,那就是獲取類型的動態類。它必須首先投射到Object,因爲否則它會打印界面名稱。由於D接口不一定是D類(它們也可以是COM對象或C++類),所以typeid並不總是可用的。強制轉換爲對象可確保它是D類,從而獲取運行時類型的詳細信息。
編輯:我看到你問新聞組以及檢查循環中的基類。下面是如何做到這一點:
你可以爲它編寫自己的元組模板,或者讓 編譯在工廠函數上失敗:A a = new T();將 失敗,如果A是不是T.
基類或接口把檢查列表看起來是這樣的:
bool checkClassList(Base, T...)() {
foreach(t; T) {
static if(!is(t : Base))
static assert(0, t.stringof ~ " is not a child of " ~ Base.stringof);
}
return true;
}
template ClassList(Base, T...) if(checkClassList!(Base, T)) {
alias ClassList = T;
}
用法:
alias list = ClassList!(A, AA, AB, AC); // good
地址:
class B {}
alias list = ClassList!(A, AA, AB, AC, B);
並獲取錯誤:
test50.d(12): Error: static assert "B is not a child of A"
test50.d(19): instantiated from here: checkClassList!(A, AA, AB, AC, B)