Rust 为什么不可变字符串可以调用string::add(mut self、other:&;str)

Rust 为什么不可变字符串可以调用string::add(mut self、other:&;str),rust,move-semantics,Rust,Move Semantics,在标准数据库中 string.rs: impl Add<&str> for String { type Output = String; #[inline] fn add(mut self, other: &str) -> String { self.push_str(other); self } } let s1 = String::from("tic"); let s2

在标准数据库中 string.rs:

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

    #[inline]
    fn add(mut self, other: &str) -> String {
        self.push_str(other);
        self
    }
}


let s1 = String::from("tic");
let s2 = String::from("tac");

let s = s1 + &s2;// it works
impl为字符串添加{
类型输出=字符串;
#[内联]
fn add(mut self,other:&str)->String{
自推式(其他);
自己
}
}
设s1=String::from(“tic”);
设s2=String::from(“tac”);
设s=s1+&s2;//它起作用了

s1在这里是不可变的,但是Add::Add(mut self,other:&str)是mut,我只想知道为什么。

当您在串联中使用它时,您借用并使用了
s1
。如果您试图在行后打印
s1
设s=s1+&s2;//它可以工作
, 将出现错误,因为它是在移动后使用的:

3 |设s1=String::from(“tic”);
|--发生移动是因为's1'的类型为'std::string::string',而该类型未实现'Copy'特性
...
6 |设s=s1+&s2;//它起作用了
|--价值转移到这里
7 | println!(“{}{}{}”,s,s1,s2);
|^^移动后在此借用的价值
s1
不需要是可变的,因为变量从未发生过变异。数据被移动并变异为变量
s

不完全是。
s1
绑定是不可变的,但是由于
add
拥有它绑定到的值的所有权,它可以用它做它想做的事情(包括对它进行变异)。由于您无法再访问该值,因此无法观察更改,这对您没有任何影响

这与肉类世界没有什么不同:如果你借给某人一些东西,而他们得到你的许可修改它,那么他们可能会这样做,但是如果你给某人一些东西,他们是否修改它不再是你的事


正如Simson所指出的,如果您尝试在添加后重用
s1
,编译器将拒绝您的代码。

AFAIK,
mut self
&mut self
不同,您的变量只能在第二种情况下可变
s1 is immutable here