当前位置: 首页 > 工具软件 > D DBI > 使用案例 >

d的内省设计(dbi)

云捷
2023-12-01

内省设计

原地址
作者:H.S.Teoh,这是中国人.
基本理念很简单,但结果却很强大.传统代码:

auto myFunc(T data) { ... }

这里T为具体整/浮/构等.然而该函数在实现中不必依赖T的所有细节.它可能只需要.前/.空的函数.
因而,这里可抽象为只要有带期望语义.前/.空的函数的任意类型.现在是:

auto myFunc(T)(T data) {
    ... //利用`.前/.空的`函数.
}

这是模板函数.而内省设计更进一步,假定.空的非必要,其只是可优化效率.因而可让无.空的类型传进来.现在,可用静如来检查它.

auto myFunc(T)(T data) {
    static if (.../*如有空的*/) {
        ... // 利用`空的/前`函数
    } else {
        ... // 无`空的`的实现.
    }
}

现在,可利用两类类型:有空的/前类型或有类型.
同样,不必限制在存在字段,也可为编译时可内省的任意属性.如基于类型大小静如来切换实现,或如何为大量实例最佳分配内存,或根据用定属来改变函数行为.
看起来作用不大,但我们可用静如来扩大适用函数的类型.静如越多适用类型越多.让函数适应调用者需求.
传统中,是每个构/类有个序化方法.这很烦人.现在:

void save(S,T)(S storage, T data) {
    static if (is(T == struct)) {
        ... // 序化构
    } else static if (is(T == class)) {
        ... // 序化类
    } else if (is(T == U[], U)) {
        ... // 序化数组
    } else if (is(T : int)) {
        ... // 序化整类
    }
    ... // 等等
    else static assert(0, "不能序化" ~ T.stringof~"类型");
}

现在,这样使用:

    S data;
	storage.save(data);
//序化S构
	int data;
	storage.save(data);
//序化整
	S[] data;
	storage.save(data);
//序化数组

超级简单.只改类型,连data都不必改.自动适应.
如果,我想让数组不一样呢,可在数组静如块前加处理静如块.

void save(S,T)(S storage, T data) {
    static if ...
    ... else if (is(T == string)) {
        ... // 特殊处理串.
    } else if (is(T == U[], U)) {
        ... // 通用数组
    } else ...
}

但如果想,特殊处理特殊类型呢?如排除某些字段.如排除下次可重新计算的存储缓存字段.此时,就可用用定属.用用定属属性标记不想保存的字段.

struct DontSerialize {}

struct MyStruct {
    int i;		// 保存
    float f;	// 保存
    @DontSerialize string s; // 不保存
}

void save(S,T)(S storage, T data) {
    ...
    static if (is(T == struct)) {
        foreach (field; allMembers!T) {
            // 跳过`DontSerialize`标记字段
            static if (!hasUDA!(mixin("data."~field), DontSerialize)) {
                ... // 这里序化.
            }
        }
    }
    ...
}

传统方法,需要黑名单/标志,而基于内省设计,都不需要.

MyStruct[] data;
storage.save(data);
//使用代码如前.

只需要用用定属标记构中字段.并添加一个处理用定属静如块,就行了.不需要大规模重构,就行了.
利用用定属,还可做很多.如用不同用定属标记不同序化机制.如可压缩数据.不必保存数据,等等.而保存接口完全一样.仍然是:

storage.save(data);

不必改动调用保存的代码.只需要标记类型定义,一切搞定.
这就是内省设计的力量.

 类似资料: