|
|
|
@ -198,6 +198,21 @@ error[E0382]: use of moved value: `s1`
|
|
|
|
|
这样就解决了我们之前的问题,`s1` 不再指向任何数据,只有 `s2` 是有效的,当 `s2` 离开作用域,它就会释放内存。 相信此刻,你应该明白了,为什么 Rust 称呼 `let a = b` 为**变量绑定**了吧?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
再来看一段代码:
|
|
|
|
|
```rust
|
|
|
|
|
fn main() {
|
|
|
|
|
let x: &str = "hello, world";
|
|
|
|
|
let y = x;
|
|
|
|
|
println!("{},{}",x,y);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
这段代码,大家觉得会否报错?如果参考之前的 `String` 所有权转移的例子,那这段代码也应该报错才是,但是实际上呢?
|
|
|
|
|
|
|
|
|
|
这段代码和之前的 `String` 有一个本质上的区别:在 `String` 的例子中 `s1` 持有了通过`String::from("hello")` 创建的值的所有权,而这个例子中,`x` 只是引用了存储在二进制中的字符串 `"hello, world"`,并没有持有所有权。
|
|
|
|
|
|
|
|
|
|
因此 `let y = x` 中,仅仅是对该引用进行了拷贝,此时 `y` 和 `x` 都引用了同一个字符串。**如果还不理解也没关系,当学习了下一章节 "引用与借用" 后,大家自然而言就会理解。**
|
|
|
|
|
|
|
|
|
|
#### 克隆(深拷贝)
|
|
|
|
|
|
|
|
|
|
首先,**Rust 永远也不会自动创建数据的 “深拷贝”**。因此,任何**自动**的复制都不是深拷贝,可以被认为对运行时性能影响较小。
|
|
|
|
@ -233,7 +248,7 @@ println!("x = {}, y = {}", x, y);
|
|
|
|
|
|
|
|
|
|
Rust 有一个叫做 `Copy` 的特征,可以用在类似整型这样在栈中存储的类型。如果一个类型拥有 `Copy` 特征,一个旧的变量在被赋值给其他变量后仍然可用。
|
|
|
|
|
|
|
|
|
|
那么什么类型是可 `Copy` 的呢?可以查看给定类型的文档来确认,不过作为一个通用的规则:**任何基本类型的组合可以是 `Copy` 的,不需要分配内存或某种形式资源的类型是 `Copy` 的**。如下是一些 `Copy` 的类型:
|
|
|
|
|
那么什么类型是可 `Copy` 的呢?可以查看给定类型的文档来确认,不过作为一个通用的规则:**保存在栈上的数据类型可以 `Copy`,任何基本类型的组合可以 `Copy` ,不需要分配内存或某种形式资源的类型是 `Copy` 的**。如下是一些 `Copy` 的类型:
|
|
|
|
|
|
|
|
|
|
* 所有整数类型,比如 `u32`。
|
|
|
|
|
* 布尔类型,`bool`,它的值是 `true` 和 `false`。
|
|
|
|
|