在D中构建字符串的首选方式

时间:2013-09-01 20:27:25

标签: d purely-functional nothrow memory-safety

关于函数属性@safepurenothrow以及父函数的编译时和运行时性能构造字符串的首选方法是什么?

我们应该使用,例如

format("Variable x=%s should equal %s", x, x_)

"Variable x=" ~to!string(x)~ " should equal " ~to!string(x_)

我认为format版本更容易看到,但在其他方面它更好吗?

编译时可能会有轻微的性能损失,因为格式字符串及其参数必须是CTFEed吗?

2 个答案:

答案 0 :(得分:1)

第一个版本通常更好。在编译性能方面没有显着差异(如果有的话,forrmat不是ctfe),而format()实际上应该表现得更好。

二进制“foo”〜“bar”的成本往往非常昂贵,因为它会分配垃圾收集器必须清理的中间结果。

在我所拥有的dmd版本中,这两个版本实际上都没有编译为安全,而不是纯粹。我认为他们用phobos git解决了这个问题,但我不确定。无论如何,现在既不实际工作,除了实现自己的功能之外,没有简单的解决方法,除非它只是用于调试。

在调试语句中放宽了纯粹的要求,你可以在@system中包含非@安全函数,并在try / catch中抛出函数来获取这些属性。

因此,这实际上会编译:

// trusted gets around safe
@trusted pure nothrow string myformat(T...)(in string fmt, in T t) {
import std.string;
    // debug gets around the pure requirement
debug try // try gets around nothrow
    return format(fmt, t);
catch(Exception e) { }

return null;
}

@safe nothrow pure void main() {
import std.conv;
string s = myformat("test %s", 10);
    assert(0, s); // the assert message shows up
}

使用-debug开关编译:dmd test.d -debug

所以不是一个很好的解决方案,但是直到具有正确属性的phobos函数被释放,或者如果你想编写自己的format()或to()函数(实际上并不那么难),你可以做int to string in < 10行)可能是你能做的最好的。

答案 1 :(得分:0)

正如接受的答案所说,更喜欢format!,并且更喜欢将format-string作为模板参数传递:

#!/usr/bin/env rdmd

module test;

import std.format; // or std.string, which publicly imports std.format
import std.stdio;

void main()
{
    writeln(format("%s%s","run-time error 'Orphan format specifier'"));
    writeln(format!"%s%s"("compile-time error 'Orphan format specifier'"));
}

DMD 2.074.0于2017年4月发布以来可用。