56用d编程用户定义属性

可给任何声明(结构,类,变量)赋值属性,然后编译时访问他们来改变编译的方式.用户定义属性完全是编译时特征.

@Encrypted string name;

可以指定多个属性.这样:

    @Encrypted @Colored string lastName;
    @(Encrypted,Colored) string address; 

属性名可为类型名,用户定义值,基本类型.禁止属性包含像42字样的字面量(意思不明).

struct Encrypted {
}

enum Color { black, blue, red }

struct Colored {
    Color color;
}

void main() {
    @Encrypted           int a;//类型名
    @Encrypted()         int b;//对象
    @Colored(Color.blue) int c;//对象
    @(42)                int d;//禁止
}

a,b的属性不同.
这样获取_ _traits(getAttributes)属性,属性含义根据需要而定.

import std.stdio;

// ...

struct Person {
    @Encrypted @Colored(Color.blue) string name;
    string lastName;
    @Colored(Color.red) string address;
}

void main() {
    foreach (attr; __traits(getAttributes, Person.name)) {//取`人.名`的属性
        writeln(attr.stringof);
    }
}

_ _traits(allMembers)按串取类型/模块的成员
_ _traits(getMember)访问成员时取一个符号.

import std.string;

// ...
void main() {
    foreach (memberName; __traits(allMembers, Person)) {
        writef("属性%-8s:", memberName);
        foreach (attr; __traits(getAttributes, __traits(getMember, Person, memberName))) {
            writef(" %s", attr.stringof);
        }

        writeln();
    }
}

_ _traits(getMember, Person, "name")生成符号Person.name
std.traits.hasUDA确定是否有用户属性.

import std.traits;
// ...
static assert(hasUDA!(Person.name, Encrypted));//有`加密`属性
static assert(hasUDA!(Person.name, Colored));
static assert(hasUDA!(Person.name, Colored(Color.blue)));

示例:

void printAsXML(T)(T object) {
// ...
    foreach (member; __traits(allMembers, T)) {
//T,类型的所有成员
        string value =__traits(getMember, object, member).to!string;  //成员值转为串
        static if (hasUDA!(__traits(getMember, T, member),Encrypted)) {//是否有加密属性,使用的是符号
        //按符号取成员,例如`Person.name`
            value = value.encrypted.to!string;
        }//加密
        writefln(` <%1$s color="%2$s">%3$s</%1$s>`, member,colorAttributeOf!(T, member), value);
    }
    //都是展开的
}

颜色属性:

    foreach (attr; __traits(getAttributes,__traits(getMember, T, memberName))) {//取属性,符号
        static if (is (typeof(attr) == Colored)) {
            return attr.color;
        }
    }

    return Color.black;
}

等价于:

void printAsXML_Person(Person object) {
// ...

    {
        string value = object.name.to!string;
        value = value.encrypted.to!string;
        writefln(`  <%1$s color="%2$s">%3$s</%1$s>`,
                 "name", Color.blue, value);
    }
    {
        string value = object.lastName.to!string;
        writefln(`  <%1$s color="%2$s">%3$s</%1$s>`,
                 "lastName", Color.black, value);
    }
    {
        string value = object.address.to!string;
        writefln(`  <%1$s color="%2$s">%3$s</%1$s>`,
                 "address", Color.red, value);
    }
}

完整程序:

import std.stdio;
import std.string;
import std.algorithm;
import std.conv;
import std.traits;

struct Encrypted {//一个构就可以了
}

enum Color { black, blue, red }//枚举

struct Colored {//默认颜色为黑
    Color color;
}

struct Person {
    @Encrypted @Colored(Color.blue) string name;
    //加密,颜色为蓝
    string lastName;//无
    @Colored(Color.red) string address;//红颜色
}
//有颜色返回指定颜色,无,为黑色
Color colorAttributeOf(T, string memberName)() {
    auto result = Color.black;

    foreach (attr;__traits(getAttributes,__traits(getMember, T, memberName))) {
        static if (is (typeof(attr) == Colored)) {
            result = attr.color;
        }
    }

    return result;
}

auto encrypted(string value) {//简单加密
    return value.map!(a => dchar(a + 1));
}

unittest {
    assert("abcdefghij".encrypted.equal("bcdefghijk"));
}
void printAsXML(T)(T object) {//见上
    writefln("<%s>", T.stringof);
    scope(exit) writefln("</%s>", T.stringof);
    foreach (member; __traits(allMembers, T)) {
        string value =__traits(getMember, object, member).to!string;
        static if (hasUDA!(__traits(getMember, T, member),Encrypted)) {
            value = value.encrypted.to!string;
        }

        writefln(`  <%1$s color="%2$s">%3$s</%1$s>`,member, colorAttributeOf!(T, member), value);
    }
}

void main() {
    auto people = [ Person("Alice", "Davignon", "Avignon"),Person("Ben", "de Bordeaux", "Bordeaux") ];
    foreach (person; people) {printAsXML(person);}
}

用户定义属性可以不改变程序只改变属性声明.如

struct Person {
    @Encrypted {
        string name;
        string lastName;
        string address;
    }//都加密了
}

// ...
printAsXML(Person("Cindy","de Cannes", "Cannes"));

也可同其他类型连用

struct Data {
    @Colored(Color.blue) string message;
}
// ...
    printAsXML(Data("hello world"));

用户定义属性可赋值给任意类型,可为类型名或值(对象)
可通过hasUDA 和 __traits(getAttributes)来改变编译程序方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值