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;

导入不能放在模块声明前,但仍可用后面导入的符号.
当前,模块声明中仅允许用定属过时.

posted @   zjh6  阅读(10)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示