update ch04-01-what-is-ownership.md

pull/249/head
xiaohulu 7 years ago
parent ad31d4c0f5
commit fdc9a6317e

@ -145,7 +145,7 @@ let s2 = s1;
这看起来与上面的代码非常类似,所以我们可能会假设他们的运行方式也是类似的:也就是说,第二行可能会生成一个 `s1` 的拷贝并绑定到 `s2` 上。不过,事实上并不完全是这样。
看看图 4-1 以了解 `String` 的底层会发生什么。`String` 由三部分组成,如图左侧所示:一个指向存放字符串内容内存的指针,一个长度,和一个容量。这一组数据存在栈上。右侧则是堆上存放内容的内存部分。
看看图 4-1 以了解 `String` 的底层会发生什么。`String` 由三部分组成,如图左侧所示:一个指向存放字符串内容内存的指针,一个长度,和一个容量。这一组数据存在栈上。右侧则是堆上存放内容的内存部分。
<img alt="String in memory" src="img/trpl04-01.svg" class="center" style="width: 50%;" />
@ -232,9 +232,9 @@ println!("x = {}, y = {}", x, y);
但这段代码似乎与我们刚刚学到的内容相矛盾:没有调用 `clone`,不过 `x` 依然有效且没有被移动到 `y` 中。
原因是像整型这样的在编译时已知大小的类型被整个存在栈上,所以拷贝其实际的值是快速的。这意味着没有理由在创建变量 `y` 后使 `x` 无效。换句话说,这里没有深浅拷贝的区别,所以这里调用 `clone` 并不会与通常的浅拷贝有什么不同,我们可以不用管它。
原因是像整型这样的在编译时已知大小的类型被整个存在栈上,所以拷贝其实际的值是快速的。这意味着没有理由在创建变量 `y` 后使 `x` 无效。换句话说,这里没有深浅拷贝的区别,所以这里调用 `clone` 并不会与通常的浅拷贝有什么不同,我们可以不用管它。
Rust 有一个叫做 `Copy` trait 的特殊注解,可以用在类似整型这样的存在栈上的类型上(第十章详细讲解 trait。如果一个类型拥有 `Copy` trait一个旧的变量在将其赋值给其他变量后仍然可用。Rust 不允许自身或其任何部分实现了 `Drop` trait 的类型使用 `Copy` trait。如果我们对其值离开作用域时需要特殊处理的类型使用 `Copy` 注解,将会出现一个编译时错误。要学习如何为你的类型增加 `Copy` 注解,请阅读附录 C 中的 “可派生的 trait”。
Rust 有一个叫做 `Copy` trait 的特殊注解,可以用在类似整型这样的存在栈上的类型上(第十章详细讲解 trait。如果一个类型拥有 `Copy` trait一个旧的变量在将其赋值给其他变量后仍然可用。Rust 不允许自身或其任何部分实现了 `Drop` trait 的类型使用 `Copy` trait。如果我们对其值离开作用域时需要特殊处理的类型使用 `Copy` 注解,将会出现一个编译时错误。要学习如何为你的类型增加 `Copy` 注解,请阅读附录 C 中的 “可派生的 trait”。
那么什么类型是 `Copy` 的呢?可以查看给定类型的文档来确认,不过作为一个通用的规则,任何简单标量值的组合可以是 `Copy` 的,不需要分配内存或某种形式资源的类型是 `Copy` 的。如下是一些 `Copy` 的类型:
@ -262,12 +262,12 @@ fn main() {
makes_copy(x); // x 应该移动函数里,
// 但 i32 是 Copy 的,所以在后面可继续使用 x
} // 这里, x 先移出了作用域,然后是 s。但因为 s 的值被移走,
} // 这里, x 先移出了作用域,然后是 s。但因为 s 的值被移走,
// 所以不会有特殊操作
fn takes_ownership(some_string: String) { // some_string 进入作用域
println!("{}", some_string);
} // 这里some_string 移出作用域并调用 `drop` 方法。释放占用的内存
} // 这里some_string 移出作用域并调用 `drop` 方法。占用的内存被释放
fn makes_copy(some_integer: i32) { // some_integer 进入作用域
println!("{}", some_integer);
@ -280,7 +280,7 @@ fn makes_copy(some_integer: i32) { // some_integer 进入作用域
### 返回值与作用域
返回值也可以转移所有权。示例 4-4 与示例 4-3 一样带有类似的注释。
返回值也可以转移所有权。示例 4-4 与示例 4-3 一样带有类似的注释。
<span class="filename">文件名: src/main.rs</span>
@ -294,7 +294,7 @@ fn main() {
let s3 = takes_and_gives_back(s2); // s2 被移动到
// takes_and_gives_back 中,
// 它也将返回值移给 s3
} // 这里, s3 移出作用域并被丢弃。s2 也移出作用域,但被移走,
} // 这里, s3 移出作用域并被丢弃。s2 也移出作用域,但被移走,
// 所以什么也不会发生。s1 移出作用域并被丢弃
fn gives_ownership() -> String { // gives_ownership 将返回值移动给

Loading…
Cancel
Save