少年辛苦终身事,莫向光阴惰寸功。这篇文章主要讲述d05用用定属来自定义相关的知识,希望能为你提供帮助。
?
??D?
?中??用定属?
?可以为??构/原始类型/编译时执行函数(返回值)?
?.
用??@TypeName?
?附加,用??__traits(getAttributes)?
?来取??用定属?
?.
enum AnEnum{a}
struct AStruct{}
class AClass{}
int FunctionThatReturnsTheUDAValue(){ return 0; }
@AnEnum
@AStruct
@AClass
@FunctionThatReturnsTheUDAValue
struct Test{}
void main()
{
import std.traits;
// __traits(getAttributes)返回符号上的所有`用定属`元组
static foreach(uda; __traits(getAttributes, Test))
pragma(msg, uda);
/*
输出:
AnEnum
AStruct
AClass
0
*/
}
还有?
?std.traits#hasUDA和std.traits#getUDAs?
?,来??有/取?
?用定属.??std.traits#getSymbolsByUDA?
?这个也很方便.struct UsefulUDA
{
string some;
int data;
}
struct NeverUsedUDA
{
}
struct MultiUDA
{
string data;
}
@UsefulUDA("Foo", 21)
@MultiUDA("Use")
@MultiUDA("Me")
@(MultiUDA("Multiple"), MultiUDA("Times"))
struct MyStruct
{
}
void main()
{
import std.traits : hasUDA, getUDAs;
import std.stdio: writeln, write;
writeln("构有@UsefulUDA?: ", hasUDA!(MyStruct, UsefulUDA));
writeln("@NeverUsedUDA呢?:", hasUDA!(MyStruct, NeverUsedUDA));
// 可多次用UDAs,getUDAs返回所有.
const UsefulUDA useful = getUDAs!(MyStruct, UsefulUDA)[0]; //要用[0]取第1个.
writeln(useful);
// 多次遍历
static foreach(uda; getUDAs!(MyStruct, MultiUDA))
write(uda.data, " ");
/*
输出:
构有@UsefulUDA?: true
@NeverUsedUDA呢?:false
const(UsefulUDA)("Foo", 21)
Use Me Multiple Times
*/
}
我们用如下?
?三个?
?属性来更新??序化器?
?.??属性? ? | 意思 |
??@Ignore? ? | 忽略字段 |
??@Name? ? | 自定义名字 |
??@ByValue? ? | 按值??序化? ?枚举,而非??名字? ?. |
?构?
?来表示??用定属?
?.struct ByValue {}
struct Ignore {}
struct Name
{
string name;
}
// 保留`Person`,用它来比较`用定属`的输出
struct Person
{
string name;
int age;
PersonType type;
}
struct PersonWithUDAs
{//带用定属的人.
@Ignore
string name;
@Name("yearsOld")
int age;
@ByValue
PersonType type;
}
实现@忽略由于?
?静每一(a)?
?的??展开?
?.??a?
?与??下?
?的合作不是很好.因而,得有点技巧.我们把??静每一?
?锁在??检查是否忽略?
?字段的??静如?
?之后.如下在序化??构/类?
?的??{{}}?
?:static foreach(member; T.tupleof)
{{
alias MemberType = typeof(member);
const MemberName = __traits(identifier, member);
MemberType memberValue = https://www.songbingjia.com/android/mixin("value." ~ MemberName);
//静每一,如果`没有`忽略字段.
static if(!hasUDA!(member, Ignore))
{
toReturn[MemberName] = serialise(memberValue);
}
}}
同样:?
?反序化?
?中这样:static foreach(member; T.tupleof)
{{
alias MemberType = typeof(member);
const MemberName = __traits(identifier, member);
static if(!hasUDA!(member, Ignore))
//但对大块代码,这很烦人.因为不能用`下`.
{
MemberType memberValue = https://www.songbingjia.com/android/deserialise!MemberType(json[MemberName]);
mixin("toReturn." ~ MemberName ~ " = memberValue; ");
}
}}
?
?目前?
?还没有??@名?
?字段.实现@名及@按值
static if(!hasUDA!(member, Ignore))
{//修改该函数内容为
JSONValue serialised = serialise(memberValue); //存储在变量中,供未来用.
static if(hasUDA!(member, Name))
//需要时,用自定义名
{
const SerialiseName = getUDAs!(member, Name)[0].name;
toReturn[SerialiseName] = serialised;
}
else // 否则用`字段名`
{
toReturn[MemberName] = serialised;
}
}
反序化:
static if(!hasUDA!(member, Ignore))
{//修改这个块.
static if(hasUDA!(member, Name))
{//名字
const SerialiseName = getUDAs!(member, Name)[0].name;
JSONValue value = https://www.songbingjia.com/android/json[SerialiseName];
}
else
{
JSONValue value = https://www.songbingjia.com/android/json[MemberName];
}
MemberType memberValue = https://www.songbingjia.com/android/deserialise!MemberType(value);
mixin("toReturn." ~ MemberName ~ " = memberValue; ");
}
?
?按值?
?://注意,在`忽略`中.
static if(!hasUDA!(member, Ignore))
{
// 存储进变量
static if(hasUDA!(member, ByValue) & & is(MemberType == enum))
{//按值.
JSONValue serialised = JSONValue(memberValue);
}
else
{//按名
JSONValue serialised = serialise(memberValue);
}
static if(hasUDA!(member, Name))
{//名字
const SerialiseName = getUDAs!(member, Name)[0].name;
toReturn[SerialiseName] = serialised;
}
else
{
toReturn[MemberName] = serialised;
}
}
同样?
?反序化?
?:【d05用用定属来自定义】
static if(!hasUDA!(member, Ignore))
{推荐阅读
- 微信for windows设置Crtl+Z撤回快捷键
- 855_linux下的JPEG格式图像无损压缩
- Centos 系统符号和正则符号总结
- Linux--网络命令/常用命令--ping/netstat/ifconfig/iptables/arp/tracepath/traceroute/tracert/route/nbstat/tftp(
- Web宝塔面板网站默认80端口被占用完美解决!
- 常用的文本文件编辑命令(续)
- ansible hosts资产文件
- Linux排查哪个进程和IP在占用网速
- linux之grep使用技巧