d定义转串

原文
提示是WebFreak的贡献.感谢他们写这篇文章!
有很多方法可自定义toString方法.方法不完全是D的一部分,而是Phobos中的约定:
.to!string时,会如下:

1,对象到串的转换调用对象toString,如果对象为null,则返回"null"串.
2,如,覆盖Object.toString
3,如果根据std.format.write准则定义,则结构到串的转换调用结构toString方法.
来自std.format.write文档:
聚集类型可定义各种toString函数.如果此函数带FormatSpec或以格式串为参数,则该函数决定接受哪些格式符.
toString应有以下签名之一:

void toString(Writer, Char)(ref Writer w, const ref FormatSpec!Char fmt)
void toString(Writer)(ref Writer w)
string toString();

其中,Writer是接受(第一个版本的类型)的输出区间.Writer不必调用模板类型.

有时无法用模板,如toString覆盖Object.toString时.此时,可用以下(较慢且不灵活)函数:

void toString(void delegate(const(char)[]) sink, const ref FormatSpec!char fmt);
void toString(void delegate(const(char)[]) sink, string fmt);
void toString(void delegate(const(char)[]) sink);

多个toString版本可用时,有Writer的版本优先级大于接收器版本.toString()串版本优先级最低.
现在在结构中定义toString最简单方法如下:

string toString() const @safe {
    import std.conv : text;

    // 如用文本, format!"", 或普通连接:
    return text(fieldA, ", ", fieldB, ", ", etc);

也可用toString(Writer)(ref Writerw)接口,但我不建议,因为在那犯的错误(如输入函数或编译错误操作),使.to!string格式(format)不再用该函数,使它无用.

但是,可结合二者:

string toString() const @safe {
    import std.array : appender;

    auto ret = appender!string;
    this.toString(ret);
    return ret.data;
}

void toString(W)(ref W writer) const @safe {
    writer.put(fieldA);
    writer.put(", ");
    writer.put(fieldB);
    writer.put(", ");
    writer.put(etc);
}

还可基于回调/接收器方法重载来覆盖串:

void toString(void delegate(const(char)[]) sink)
{
    sink(fieldA);
    sink(", ");
    sink(fieldB);
    sink(", ");
    sink(etc);
}

缺点是,不能按@safe,nothrow,pure,等标记接收器.也不能限制接收器复制属性.但是,可在此抓编译器错误,因此比仅用基于Writer方法要好.

定义WritertoString方法,及用appender!string调用writertoString很可靠,可抓大多数错误,如果确实无法编译奇怪的writer类型,也可回退到用追加器.

未来可改进writer重载调用.不应检查

__traits(compiles, ...)
//或
is(typeof(...))

而应,检查是否有给定签名方法,然后试调用它.(也许需要无需试编译,就可查看是否有潜在匹配的函数重载的一些特征?)

现在,可基于接收器和写者(sink/writer)方法自定义格式说明.这里维基

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