d中类型对象实现元编程
原文
受Hana
启发.
如果想实现找出
包含类型
的最大大小
.在D
中这很容易
import std.meta: AliasSeq;
import std.traits: Largest;
alias Types = AliasSeq!(int, float, char, double);
enum maxSize = Largest!(Types).sizeof;
writeln(maxSize);//8 bytes
Largest
实现不好看(递归
),略
.不用模板
来计算类型
.用普通函数,创建类型对象:
import std.traits: isInstanceOf;
enum isType(T) = isInstanceOf!(Type, T);
struct Type(T){
alias type = T;
string toString()
{
return "Type!("~T.stringof~")";
}
}
enum t = Type!(int)();
enum t1 = Type!(string)();
这样,按普通对象
一样使用类型
,如下判断类型
是否相同:
enum equals(A,B)(Type!A, Type!B){
return is(A == B);
}
enum t = Type!(int)();
enum t1 = Type!(string)();
writeln(t.equals(t1)); // false
writeln(equals(t, t1)); // false
writeln(equals(Type!int(), Type!int())); // true
创建TypeTuple
来容纳多个类型.
enum isTypeTuple(T) = isInstanceOf!(TypeTuple, T);
struct TypeTuple(Types...){
import std.meta: allSatisfy;
static assert(allSatisfy!(isType, Types), "可变参,要求是`类型`类型");
Types expand;
alias expand this;
string toString()
{
import std.range;
string[] s;
foreach(t; expand){
s~= t.toString();
}
return "TypeTuple!(" ~ s.join(", ") ~")";
}
}
enum typeTuple(Types...)(Types){
return TypeTuple!Types();
}
顺便,用toString
打印生成
类型,避免伪码.
enum types = TypeTuple!(Type!int, Type!char, Type!float, Type!double)();
//or
enum types = typeTuple(Type!int, Type!char, Type!float, Type!double);
辅助函数:
enum tupleFromTypes(Ts...)(){//类型元组.
import std.meta: staticMap;
return TypeTuple!(staticMap!(Type, Ts))();
}
enum types = tupleFromTypes!(int,double, int,float);
实现元函数:
//过滤
enum filter(alias f, Tup)(Tup){
static assert(isTypeTuple!(Tup), tup.stringof~" 不是类型元组.");
enum tup = Tup();
static if(tup.length == 0){
return typeTuple();
}
else static if(f(tup[0])){
return typeTuple(tup[0], filter!(f)(typeTuple(tup[1..$])).expand);
}
else{
return filter!(f)(typeTuple(tup[1..$]));
}
}
//使用
enum types = tupleFromTypes!(int, double, string, float);
enum biggerThan4 = filter!(t => t.type.sizeof > 4)(types);
writeln(biggerThan4);// TypeTuple!(Type!(double), Type!(string))
//映射
enum map(alias f, Tup)(Tup){
static assert(isTypeTuple!(Tup), tup.stringof~" is not a TypeTuple.");
enum tup = Tup();
static if(tup.length == 0){
return typeTuple!();
}
else{
return typeTuple(f(tup[0]), map!(f)(typeTuple(tup[1..$])).expand);
}
}
enum types = tupleFromTypes!(int, double, string, float);
enum onlyInts = map!(t => Type!int())(types);
writeln(onlyInts);// TypeTuple!(Type!(int), Type!(int), Type!(int), Type!(int))
//
enum types = tupleFromTypes!(int, double, string, float);
enum smallerThan5 = map!((t){
static if(t.type.sizeof > 4){
return Type!int();
}
else{
return t;
}
})(types);// TypeTuple!(Type!(int), Type!(int), Type!(int), Type!(float))
writeln(smallerThan5);
要在编译时运行,请用静如
.
enum indexOf(T,Tup)(T, Tup){
static assert(isTypeTuple!(Tup), tup.stringof~" is not a TypeTuple.");
static assert(isType!(T), T.stringof~" is not a Type.");
enum t = T();
enum tup = Tup();
foreach(index, type; tup.expand){
if(type.equals(t)){
return index;
}
}
return -1;
}
enum types = tupleFromTypes!(int, double, string, float);
enum index = indexOf(Type!string(), types);
writeln(index);// 2
//快排
enum partition(alias f, Tup)(Tup){//分区
enum tup = Tup();
return partitionImpl!(f)(tup, typeTuple(), typeTuple());
}
enum partitionImpl(alias f, Tup, TupLeft, TupRight)(Tup, TupLeft, TupRight){
import std.typecons: tuple;
enum tup = Tup();
enum l = TupLeft();
enum r = TupRight();
static if(tup.length == 0){
return tuple(l, r);
}
else{
static if(f(tup[0])){
return partitionImpl!(f)(typeTuple(tup[1..$]), typeTuple(tup[0], l.expand), typeTuple(r.expand));
}
else{
return partitionImpl!(f)(typeTuple(tup[1..$]), typeTuple(l.expand), typeTuple(tup[0], r.expand));
}
}
}
enum sort(alias f,Tup)(Tup){
enum tup = Tup();
static if(tup.length == 0){
return typeTuple();
}
else static if(tup.length == 1){
return typeTuple(tup[0]);
}
else{
enum middle= tup[0];
enum t = partition!(t => f(t, middle))(typeTuple(tup[1..$]));
enum left = t[0];
enum right = t[1];
return typeTuple(left.expand, middle, right.expand);
}
}
//使用
enum types = tupleFromTypes!(int, double, string, float);
enum sortedTypes = sort!((t1, t2) => t1.type.sizeof > t2.type.sizeof)(types);
writeln(sortedTypes);// TypeTuple!(Type!(string), Type!(double), Type!(int), Type!(float))
//最大尺寸
enum types = tupleFromTypes!(int, double, string, float);
enum sortedTypes = sort!((t1, t2) => t1.type.sizeof > t2.type.sizeof)(types);
enum maxSize = sortedTypes[0].sizeof;
writeln(maxSize);// 8字节
类型对象
使元编程
就像使用普通函数
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现