d查找特定属性的所有函数
Processing: module main
Processing: module object
Processing: module c
Processing: module attr
test2() has sillyWalk
main() has sillyWalk
需要快速查看c.d,b.d
和main.d
以了解其用法.main.d
的onEach
函数处理每次
帮助函数找到的命中
,这里只是打印名
.在main
函数中,你会看到一个疯狂mixin(__MODULE__)
,用来按迭代起点
取当前模块
的引用
.
注意,main.d
文件顶部有module project.main;
一行,如果模块名仅为main
,那么mixin
黑客会混淆main
模块与函数
.
现在,注意attr.d
.
module attr;
struct sillyWalk { int i; }
enum isSillyWalk(alias T) = is(typeof(T) == sillyWalk);
import std.typetuple;
alias hasSillyWalk(alias what) = anySatisfy!(isSillyWalk, __traits(getAttributes, what));
enum hasSillyWalk(what) = false;
alias helper(alias T) = T;
alias helper(T) = T;
void allWithSillyWalk(alias a, alias onEach)() {
pragma(msg, "Processing: " ~ a.stringof);
foreach(memberName; __traits(allMembers, a)) {
// 保证避免错误
static if(__traits(compiles, __traits(getMember, a, memberName))) {
alias member = helper!(__traits(getMember, a, memberName));
// pragma(msg, "查看" ~ memberName);
import std.string;
static if(!is(typeof(member)) && member.stringof.startsWith("module ")) {
enum mn = member.stringof["module ".length .. $];
mixin("import " ~ mn ~ ";");
allWithSillyWalk!(mixin(mn), onEach);
}
static if(hasSillyWalk!(member)) {
onEach!member;
}
}
}
}
首先,有属性定义
和一些帮助器
来检测它的存在.只需扫描属性元组
来查找感兴趣
类型.
helper
模板是缩写重复__traits(getMember)
调用的技巧,它只是别名
为更好名
,同时避免编译器
中出现愚蠢的解析错误
.
最后,有了步行者
.它循环了allMembers
.
接着,第一个static if
只是确保可真正
获得想要获得成员.没有它,它会在获取自动导入object
模块的私有成员
时抛错误.
函数结尾也很简单,它只是在每个元素上调用onEach
.中间有点神奇:它检测到导入
模块,在此导入,通过mixin(module)
顶层技巧访问它,然后通过导入图
递归.
dmd main.d attr.d b.d c.d
也有些限制:
1,可以进入类/结构
成员,但这里
没有实现.不过非常
简单:如果成员
是类,也只需递归
进入它.
2,如果模块
与成员
共享名,则可能会中断
,如main
示例.用带有一些包点
的唯一模块名
来解决问题它.
3,它不会下降
到函数本地导入
,
使用UDA
添加代码总是很麻烦,在此更是,因为onEach
是具有域
的函数.不过,也许可构建全局
关联闭包
void delegate()[string] handlers;
/* ... */
handlers[memberName] = &localHandlerForThis;
大多数D代码,不需要如上遍历导入树
,只是要求你,在使用它的单个聚集或模块
中:
mixin UdaHandler!T;
或在每个
之后:
mixin RegisterSerializableClass!MyClass;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现