d的匿名类
原地址
作者:亚当
.
D
也有匿名类.
class A {}
A foo() {
return new class A {
override string toString() {
return "匿名!";
}
};
不必给出基类,默认为对象
.
Object foo() {
return new class {
// 内容
};
}
你甚至可以实现父和接口:
interface I { int getInt(); }
class Base { string getString() { return "串"; } }
I foo() {
return new class Base, I {
int getInt() { return 15; }
};//基类,实现接口
}
void main() {
import std.stdio;
I i = foo();
writeln(i.getInt());
Base b = cast(Base) i;
writeln(b.getString());
}
很酷,有时可节约你单独写类定义.当然,函数中你也可嵌套类并同样访问局部变量.多种写法.
你可与d
的自动返回
结合起来,就有了到匿名类型
的引用,而不仅是基/接口
.
auto foo() {
return new class {
int i;
};
}
为什么很酷呢?因为你可在上面用d
的反射.
auto foo() {
return new class {
int i;
};
}
void main() {
auto f = foo();
//显示`i`和自动生成的`本`构造器
pragma(msg, __traits(derivedMembers, typeof(f)));
}
D
禁止在表达式
环境中声明
.因而对反射,匿名类
用来传递偶尔
用的东西是很方便的.但规范
禁止按模板值参
发送类对象
.所以你得在ctfe
端严格
或严格
按类型来工作.
template some_cool_thing(T) {
pragma(msg, __traits(derivedMembers, T));
}
void main() {
some_cool_thing!(typeof(new class {
int y;
}));//严格按类型
}
typeof(new class { })
是合法的,不用单独写名字来聚集声明
.但有用吗?..可能!但相比直接单独写声明
太冗长了.
总之,可在函数中简单快速匿名分组
.也可搞笑
的替换元组
,但明显是类分配
.
对局部变量,你可以scope i = new class {};
,这样不必分配.
void main() @nogc {
scope a = new class {
int a = 5;
};
import core.stdc.stdio;
printf("%d\n", a.a);
}
你不能返回它,只能作为局部变量.
dmd -betterC
也接收该函数,但由于缺少d运行时
而链接失败,但,下面小程序在betterC
中工作.
extern(C++) class O {
extern(D)
abstract int omg();
}
extern(C)
int main() @nogc {
scope a = new class O {
int a = 5;
override int omg() { return a; }
};
import core.stdc.stdio;
printf("%d\n", a.a);
return 0;
}
dmd -betterC
管用了.我用匿名类
来实现com
.还可以.很酷,很有用.
类的域
覆盖局部域
!
class A {
int a;
}
A foo() {
int a;
return new class A {
this() {
//这里,A.a的引用,非上面的`a`.
//this,自赋值
this.a = a; // 不干活
}
};
}
父类,看起来更近
,你容易忘记是自己
在子类
里面,而且编译器
不会警告你
.
上面是经验,你如何传递本地变量
进来呢?匿名类
有构造参数吗?
但规范中有,语法很怪
,如下:
void main() {
int a = 83;
auto obj = new class (a) {//(a)为构造构造器的参数列表.
this(int a) {
import std.stdio;
writeln("传递进来了", a);
}
};
}
参数列表
在基类/接口
前,在类
关键字后.
new
后还可有分配器
参数.
一般,你写new Object(args)
,所以,我试了new class Base(args)/ new class { ... } (args);
,但没用.最后查规范
找到.注意,D
有模板参数.
总之,这样,本地变量与类成员
不会冲突.
小技巧
你可在模板声明前放用定属
.
@foo module whatever;
import module_with_foo;
导入不能放在模块声明
前,但仍可用后面导入的符号.
当前,模块声明
中仅允许用定属
和过时
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现