为什么字符串连接只消耗第一个字符串?

109*_*149 3 rust

当我遇到这个时,我正在阅读锈书

fn main() {
    let s1 = String::from("Hello, ");
    let s2 = String::from("world!");
    let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used
}
Run Code Online (Sandbox Code Playgroud)

事实证明,'+操作员使用的add方法,其签名看起来像这样':

fn add(self, s: &str) -> String { // ... }
Run Code Online (Sandbox Code Playgroud)

我明白为什么s1被“消耗”并且以后不再可用的原因。但是为什么 rust 会这样呢?我的意思是,为什么方法不能add将 self ( &self) 作为第一个参数的引用,以便该s1字符串可供以后使用?

pro*_*-fh 8

如果签名是fn add(&self, s:&str)这将意味着,即使在调用的上下文中的第一个参数(被称为self)可以被消耗(因为不再使用之后),该add()函数将不得不通过以与延长其克隆这个字符串开始s.

另一方面,使用forself可以重用原始字符串以直接扩展它而无需克隆。

这种情况同时是最有效和最普遍的,因为如果您真的想保留原始字符串,您始终可以在调用add().

fn main() {
    let s1 = String::from("Hello, ");
    let s2 = String::from("world!");
    let s3 = s1 + &s2;
    // println!("s1: {}", s1); // borrow of moved value: `s1`
    println!("s2: {}", s2);
    println!("s3: {}", s3);
    println!("~~~~~~~~~~~~~~~~");
    let s1 = String::from("Hello, ");
    let s2 = String::from("world!");
    let s3 = s1.clone() + &s2;
    println!("s1: {}", s1); // not consumed by +
    println!("s2: {}", s2);
    println!("s3: {}", s3);
}
Run Code Online (Sandbox Code Playgroud)