d从串名调用类
import std.stdio;
class Math {
static string noArgs(string[] s) { writeln(s); return ""; }
static string withOneArg(string[] s) { writeln(s); return ""; }
static string withTwoArgs(string[] s) { writeln(s); return ""; }
}
class String {
static string oneArg(string[] s) { return null; }
}
string execute(string what, string[] params) {
import std.string;
auto parts = what.split(".");
auto className = parts[0];
auto methodName = parts[1];
import std.typetuple;
switch(className) {
default: assert(0, "未知类");
foreach(possibleClass; TypeTuple!(Math, String)) {//可能类.
case possibleClass.stringof:
switch(methodName) {
default: assert(0, "未知方法");
foreach(memberName; __traits(derivedMembers, possibleClass)) {//成员名
case memberName:
return __traits(getMember, possibleClass, memberName)(params);//调用
break;
}
}
break;
}
}
assert(0);
}
void main() {
execute("Math.withOneArg", ["cool"]);
execute("String.oneArg", ["cool"]);
}
请注意,没有使用mixin 式
.我没有从串
中获取类的实例
,而是用TypeTuple
包含需要的类.在不同域内使用时,比mixin
更好,因为不太可能找到名类
;如果possibleClasses
是从不同模块执行
的编译时参数,则类列表
仍然有效,而串列表
看到未定义
的标识
错误,因为库模块
不导入你的用户模块
.
我删除的另一个mixin
是生成若的那个.这很疯狂,
可有编译时
的每一
,__traits
等.甚至可在他们里面放case
.
所以,只需在要比较的运行时变量
上写普通switch
语句,把它放在foreach
里面循环搜索编译时东西,case that_loop_var
:然后就好了.
同样,我使用__traits(getMember)
而不是mixin
串来调用该方法.来避免名字冲突,并且代码
更简洁.如果需要,还可处理重载(使用__traits(getOverloads)
而不是__traits(getMember)
,可循环遍历
每个重载并匹配参数类型
).
最后,允许在其他case
语句中的嵌套switches
.如果要跳出外部循环或switch
,又不想出现歧义
,可标记循环和开关
,并使用break label_name_here;
来退出.continue
一样.
std.traits.ParameterTypeTuple
和ReturnType
很好用.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现