考虑我有以下课程:
/// File classes.d
class C {
string type() { return "C"; };
}
class C1 : C {
override string type() { return "C1"; };
}
class C2 : C {
override string type() { return "C1"; };
}
Run Code Online (Sandbox Code Playgroud)
现在我想在其他地方实施工厂,例如:
/// File factory.d
module factory;
import std.functional;
import std.stdio;
void main() {
mixin(import("classes.d"));
auto c = cast(typeof(mixin("C1"))) Object.factory("C1");
writeln(c.type());
}
Run Code Online (Sandbox Code Playgroud)
编译器(dmd 2.058)说:
factory.d(7): Error argument C1 to typeof is not an expression
Run Code Online (Sandbox Code Playgroud)
我知道以下行汇编得很好:
auto c = cast(C1) Object.factory("classes.C1");
Run Code Online (Sandbox Code Playgroud)
但这需要我在编译时知道类型(C1).我想在运行时获取类型(如字符串).
mixin(`auto c = cast(typeof(C1)) Object.factory("C1");`)
Run Code Online (Sandbox Code Playgroud)
我不明白你的问题,我想:你想在运行时动态地转换为给定的类型?这在静态类型语言中是不可能的!你可以做的是,传递你的类(或其他)作为void*和使用开关...案例将其转换为所需的类型(你也可以使用std.variant,这可能是更好的方式,但我从来没有使用它)和然后调用不同的函数(模板化函数):
final switch(which_type) {
case "C1": foo(cast(C1)bar); break;
case "C2": foo(cast(C2)bar); break;
}
void foo(T)(T a) {
}
Run Code Online (Sandbox Code Playgroud)
您还可以在编译时生成switch case:
final switch(which_type) {
foreach(i; TypeTuple("C1", "C2")) {
case i: foo(mixin(`cast(` ~ i ~ `)bar`); break;
}
}
Run Code Online (Sandbox Code Playgroud)
如果你只是想获得该类型的字符串typeof(bar).stringof将给你类型的bar字符串(但这在编译时已知).
Mixins是一个编译时工件,只能在编译时使用.typeof只能在编译时使用.D是静态类型语言,所有类型必须在编译时知道.
您可以引用引用类实例的基类类型,因此可以这样:
C makeC(string type)
{
switch(type)
{
case "C": return new C;
case "C1": return new C1;
case "C2": return new C2;
default: throw new Exception(format("%s is not a C", tye));
}
}
C c = makeC("C1");
Run Code Online (Sandbox Code Playgroud)
还std.variant可以使用它来保存不同类型(它在内部使用联合).
但是你无法决定变量在运行时的类型,因为D是静态类型的.