连接字符串的"标准"方法是什么?

Bit*_*ler 13 rust

虽然我基本了解它们之间是什么str以及std::string::String它们是如何相互关联的,但我发现从各个部分组成字符串而不花费太多时间和思考它有点麻烦.像往常一样,我怀疑我还没有看到正确的方法,这使它变得直观和轻而易举.

let mut s = std::string::String::with_capacity(200);
let precTimeToJSON = | pt : prectime::PrecTime, isLast : bool | {
    s.push_str(
        "{ \"sec\": " 
       + &(pt.sec.to_string()) 
       + " \"usec\": " 
       + &(pt.usec.to_string()) 
       + if isLast {"}"} else {"},"})
    };    
Run Code Online (Sandbox Code Playgroud)

上面的代码由编译器支持,错误消息如下:

src\main.rs:25:20:25:33错误:二进制操作+无法应用于类型&'static str[E0369]

即使经过半个小时的摆弄和随机添加&,我也无法使这个可编辑.那么,我的问题在这里:

  • 为了达到显而易见的目的,我需要写些什么?
  • 在Rust中执行此操作的"标准"方法是什么?

Geo*_*ard 19

Rust编译器是正确的(当然):+字符串文字没有运算符.

我相信format!()是做你想做的事的惯用方法.它使用std::fmt语法,它基本上由格式化字符串和格式化参数组成(a la C printf).对于您的示例,它看起来像这样:

let mut s: String = String::new();
let precTimeToJSON = | pt : prectime::PrecTime, isLast : bool | {
    s = format!("{{ \"sec\": {} \"usec\": {} }}{}",
        pt.sec,
        pt.usec,
        if isLast { "" } else { "," }
    )
};
Run Code Online (Sandbox Code Playgroud)

因为它是一个宏,所以你可以自由地在参数列表中混合类型,只要该类型实现了std::fmt::Display特征(对于所有内置类型都是如此).此外,您必须分别逃避文字{}as {{}}.最后,请注意格式字符串必须是字符串文字,因为宏会解析它,并且扩展代码看起来与原始format!表达式不同.

这是上面例子的游乐场链接.

还有两点可以帮到你.首先,如果您正在阅读和编写JSON,请查看诸如rustc-serialize之类的库.它不那么痛苦!

其次,如果您只想连接&'static str字符串(即字符串文字),则可以使用concat!()宏实现零运行时成本.在上面的情况下它不会帮助你,但它可能与其他类似的一样.

  • 一个很好的答案,但是考虑到使用`push_str`和`isLast`参数的存在,我怀疑OP正在将一个循环中的值累积到一个`String`中.在这种情况下,在循环体中使用`write!`宏会更有效地附加到编写器而不是重复创建```````!`只能将其位复制到`s`并丢弃它. (6认同)