关于rust:如何连接字符串?

How do I concatenate strings?

如何连接以下类型的组合:

  • strstr
  • Stringstr
  • StringString


连接字符串时,需要分配内存以存储结果。最容易开始的是String&str

1
2
3
4
5
6
7
fn main() {
    let mut owned_string: String ="hello".to_owned();
    let borrowed_string: &str ="world";

    owned_string.push_str(borrowed_string);
    println!("{}", owned_string);
}

在这里,我们拥有一个可以突变的拥有的字符串。这是有效的,因为它可能使我们可以重用内存分配。 StringString也有类似的情况,因为&String可以取消引用为&str

1
2
3
4
5
6
7
fn main() {
    let mut owned_string: String ="hello".to_owned();
    let another_owned_string: String ="world".to_owned();

    owned_string.push_str(&another_owned_string);
    println!("{}", owned_string);
}

此后,another_owned_string保持不变(请注意没有mut限定符)。还有另一个变体使用String,但不要求它是可变的。这是Add特征的一种实现,该特征以String作为左侧,而&str作为右侧:

1
2
3
4
5
6
7
fn main() {
    let owned_string: String ="hello".to_owned();
    let borrowed_string: &str ="world";

    let new_owned_string = owned_string + borrowed_string;
    println!("{}", new_owned_string);
}

请注意,在调用+之后,不再可以访问owned_string

如果我们想产生一个新的字符串而又保持不变,该怎么办?最简单的方法是使用format!

1
2
3
4
5
6
7
fn main() {
    let borrowed_string: &str ="hello";
    let another_borrowed_string: &str ="world";

    let together = format!("{}{}", borrowed_string, another_borrowed_string);
    println!("{}", together);
}

请注意,两个输入变量都是不可变的,因此我们知道它们没有被触及。如果我们想对String的任何组合执行相同的操作,则可以使用String也可以格式化的事实:

1
2
3
4
5
6
7
fn main() {
    let owned_string: String ="hello".to_owned();
    let another_owned_string: String ="world".to_owned();

    let together = format!("{}{}", owned_string, another_owned_string);
    println!("{}", together);
}

但是,您不必使用format!。您可以克隆一个字符串,然后将另一个字符串附加到新字符串:

1
2
3
4
5
6
7
fn main() {
    let owned_string: String ="hello".to_owned();
    let borrowed_string: &str ="world";

    let together = owned_string.clone() + borrowed_string;
    println!("{}", together);
}

注意-我所做的所有类型说明都是多余的-编译器可以在这里推断所有正在使用的类型。我添加它们只是为了使对Rust刚接触的新手清楚,因为我希望这个问题在该小组中很受欢迎!


要将多个字符串连接成一个字符串,并用另一个字符分隔,有两种方法。

我见过的最好的方法是在数组上使用join方法:

1
2
3
4
5
6
7
8
fn main() {
    let a ="Hello";
    let b ="world";
    let result = [a, b].join("\
");

    print!("{}", result);
}

根据您的用例,您可能还希望获得更多控制权:

1
2
3
4
5
6
7
8
fn main() {
    let a ="Hello";
    let b ="world";
    let result = format!("{}\
{}", a, b);

    print!("{}", result);
}

我见过一些其他手动方式,有些在这里和那里避免一两个分配。出于可读性考虑,我发现以上两项已足够。


我认为concat方法和+也应在这里提及:

1
2
3
4
assert_eq!(
  ("My".to_owned() +"" +"string"),
  ["My","","string"].concat()
);

还有concat!宏,但仅用于文字:

1
2
let s = concat!("test", 10, 'b', true);
assert_eq!(s,"test10btrue");


在RUST中连接字符串的简单方法

在RUST中可以使用多种方法来连接字符串

第一种方法(使用concat!()):

1
2
3
fn main() {
    println!("{}", concat!("a","b"))
}

上面代码的输出是:

ab


第二种方法(使用push_str()+运算符):

1
2
3
4
5
6
7
8
9
10
11
fn main() {
    let mut _a ="a".to_string();
    let _b ="b".to_string();
    let _c ="c".to_string();

    _a.push_str(&_b);
   
    println!("{}", _a);
 
    println!("{}", _a + &_b);
}

上面代码的输出是:

ab

abc


第三种方法(Using format!()):

1
2
3
4
5
6
7
fn main() {
    let mut _a ="a".to_string();
    let _b ="b".to_string();
    let _c = format!("{}{}", _a, _b);
   
    println!("{}", _c);
}

上面代码的输出是:

ab

检查一下并尝试使用Rust游戏场地


2020更新:通过字符串插值进行串联

RFC 2795发布于2019-10-27:
建议支持隐式参数以执行许多人所熟知的"字符串插值"操作-一种将参数嵌入字符串中以将其串联的方法。

RFC:https://rust-lang.github.io/rfcs/2795-format-args-implicit-identifiers.html

最新的发行状态可以在这里找到:
https://github.com/rust-lang/rust/issues/67984

在撰写本文时(2020-9-24),我相信该功能应该在Rust Nightly构建中可用。

这将允许您通过以下简写方式进行连接:

1
format_args!("hello {person}")

等效于:

1
format_args!("hello {person}", person=person)

还有" ifmt"板条箱,它提供了自己的一种字符串插值方式:

https://crates.io/crates/ifmt