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;
}
}
浙公网安备 33010602011771号