You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中为何两个String无法直接拼接,String与&str却可以?

为什么Rust中两个String不能直接用+拼接,而String和&str可以?

在《Rust Book》第四章“变量与数据的交互方式:Clone”中提到,可用.clone()方法复制String,示例代码能正常运行:

let s1 = String::from("hello");
let s2 = s1.clone();

println!("s1 = {}, s2 = {}", s1, s2);

但如果尝试将s2赋值为s1.clone() + s1.clone(),就会触发类型不匹配的编译错误:

error[E0308]: mismatched types
 --> src/main.rs:3:24
  |
3 |     let s2 = s1.clone() + s1.clone();
  |                           ^^^^^^^^^^
  |                           |
  |                           expected `&str`, found struct `String`
  |                           help: consider borrowing here: `&s1`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `comment` due to previous error

把右侧的s1.clone()改为&s1.clone()即可修复问题,背后的逻辑如下:

核心原因:+运算符的定义规则

Rust里的+运算符对应std::ops::Addtrait的实现,针对String的实现简化后是这样的:

impl Add<&str> for String {
    type Output = String;

    fn add(mut self, rhs: &str) -> String {
        self.push_str(rhs);
        self
    }
}

简单说:

  • 左操作数必须是拥有所有权的String:用mut self是为了直接复用原字符串的内存空间,避免额外分配,拼接后原String的所有权会被转移,无法再被使用。
  • 右操作数必须是**&str类型的引用**:&str是字符串的切片引用,能兼容所有字符串相关的引用(比如&String会通过Deref强制转换自动变成&str)。

为什么String + String不合法?

当你写s1.clone() + s1.clone()时,左操作数是String符合要求,但右操作数也是String,并不匹配Add<&str>的参数定义。Rust不会自动把右操作数的String转为&str——因为这涉及所有权问题,自动转换会导致原String的所有权处理模糊,所以编译器明确要求你提供引用类型。

为什么&s1.clone()能解决问题?

&s1.clone()会创建一个指向克隆出的String的引用&String,而Rust的Deref强制转换机制会自动把&String转换成&str,刚好匹配Add trait的参数要求。当然更简洁的写法是直接用&s1(无需克隆,只是借用原字符串内容),或者用format!("{}{}", s1.clone(), s1.clone())这种更直观的拼接方式。

内容的提问来源于stack exchange,提问作者Conrad Parker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 09:01:02