为什么不可变字符串可以调用 String::add(mut self, other: &str)
Why immutable string can call String::add(mut self, other: &str)
在stdlib
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
s1在这里是不可变的,但是Add::add(mut self,other:&str)是mut,我只想想知道为什么。
你在串联中使用它时,你借用并消耗了s1
。如果您尝试在行后打印 s1
let s = s1 + &s2;// it works
,
会报错,因为在move之后使用:
3 | let s1 = String::from("tic");
| -- move occurs because `s1` has type `std::string::String`, which does not implement the `Copy` trait
...
6 | let s = s1 + &s2;// it works
| -- value moved here
7 | println!("{}{}{}",s,s1,s2);
| ^^ value borrowed here after move
s1
不需要是可变的,因为变量永远不会发生变化数据被移动并突变为变量 s
.
s1 is immutable here
不完全是。 s1
绑定是不可变的,但由于 add
拥有它绑定到的值的所有权,它可以用它做它想做的事(包括改变它) .由于您无法再访问该值,因此您无法观察到更改,这对您没有任何影响。
它与肉类世界没有什么不同:如果你 借给 一些东西给某人并且他们得到你修改它的许可那么他们可能会这样做,但是如果你 给某人一些东西,无论他们修改它是你的事none。
正如 Simson 指出的那样,如果您在添加后尝试重用 s1
,编译器将拒绝您的代码。
在stdlib 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
s1在这里是不可变的,但是Add::add(mut self,other:&str)是mut,我只想想知道为什么。
你在串联中使用它时,你借用并消耗了s1
。如果您尝试在行后打印 s1
let s = s1 + &s2;// it works
,
会报错,因为在move之后使用:
3 | let s1 = String::from("tic");
| -- move occurs because `s1` has type `std::string::String`, which does not implement the `Copy` trait
...
6 | let s = s1 + &s2;// it works
| -- value moved here
7 | println!("{}{}{}",s,s1,s2);
| ^^ value borrowed here after move
s1
不需要是可变的,因为变量永远不会发生变化数据被移动并突变为变量 s
.
s1 is immutable here
不完全是。 s1
绑定是不可变的,但由于 add
拥有它绑定到的值的所有权,它可以用它做它想做的事(包括改变它) .由于您无法再访问该值,因此您无法观察到更改,这对您没有任何影响。
它与肉类世界没有什么不同:如果你 借给 一些东西给某人并且他们得到你修改它的许可那么他们可能会这样做,但是如果你 给某人一些东西,无论他们修改它是你的事none。
正如 Simson 指出的那样,如果您在添加后尝试重用 s1
,编译器将拒绝您的代码。