d转串的最佳实践

原文
GC按需分配和释放串速度相比,人类阅读速度非常慢.
FormatSpec只在toString实现中用做有用事情时,才用它.要提供默认说明符的方便重载.

struct A {
    string message;
    int enthusiasm;

    void toString(DG)(scope DG sink) scope const @safe
        if(is(DG : void delegate(scope const(char[])) @safe)
        || is(DG : void function(scope const(char[])) @safe))
    {
        import std.format : formattedWrite;
        sink(message);
        sink(" x ");
        formattedWrite!"%d"(sink, enthusiasm);
        sink("!");
    }
    string toString() scope const pure @safe {
        StringBuilder builder;
        toString(&(builder.opCall)); // 找精确长
        builder.allocate();
        toString(&(builder.opCall)); // 实际写
        return builder.finish();
    }
}

第一个toString重载定义了如何按文本格式化值,而第二个重载管理内存,并转发格式化工作给第一个.

struct StringBuilder {//实用工具.关键简单.
private:
    char[] buffer;
    size_t next;

public:
    void opCall(scope const(char[]) str) scope pure @safe nothrow @nogc {
        const curr = next;
        next += str.length;
        if(buffer !is null)
            buffer[curr .. next] = str[];
    }
    void allocate() scope pure @safe nothrow {
        buffer = new char[next];
        next = 0;
    }
    void allocate(const(size_t) maxLength) scope pure @safe nothrow {
        buffer = new char[maxLength];
        next = 0;
    }
    string finish() pure @trusted nothrow @nogc {
        assert(buffer !is null);
        string ret = cast(immutable) buffer[0 .. next];
        buffer = null;
        next = 0;
        return ret;
    }
}
posted @ 2022-10-05 16:19  zjh6  阅读(25)  评论(0)    收藏  举报  来源