原文结构
可以是函子
:
private @safe struct TranslatableStringPlural
{
string _str, _strpl;
this(string s1, string s2) { // 必须的!
_str = s1;
_strpl = s2;
}
string opCall(int n)
{
auto fmt = ngettext(_str, _strpl, n);
if (countFormatSpecifiers(fmt) == 0)
// 改进该行.
return ()@trusted{ return fromStringz(&(format(fmt~"\0%s", n)[0])); }();
return format(fmt, n);
}
}
现在,变成:
private @safe struct Strplusarg {
this(string s) {
fmt = s;
auto fs = countFormatSpecifiers(fmt);
//修复这句.
assert(fs==0||fs==1,"无效");
hasArg = fs == 1;
}
string fmt;
bool hasArg;
}
private @safe struct TranslatableStringPlural
{
//...前略
string opCall(int n)
{
auto f = n == 1 ? _str : _strpl;
return f.hasArg ? format(f.fmt, n) : f.fmt;
}
}
原代码:
@safe: private:
int countFormatSpecifiers(string fmt) pure
{
int count = 0;
auto f = FormatSpec!char(fmt);
if (!__ctfe)
{//有ctfe
while (f.writeUpToNextSpec(nullSink))
count++;
} else {
auto a = appender!string;
while (f.writeUpToNextSpec(a))
count++;
}
return count;
}
修复为:
@safe: private:
int countFormatSpecifiers(string fmt) pure
{
static void ns(const(char)[] arr) {}
// 最简输出区间.
auto nullSink = &ns;
int count = 0;
auto f = FormatSpec!char(fmt);
while (f.writeUpToNextSpec(nullSink))
count++;
return count;
}