mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-01-19 04:48:12 +02:00
parent
fe40ef54e5
commit
b83dd9a1f9
433
po/zh-CN.po
433
po/zh-CN.po
@ -4371,7 +4371,7 @@ msgstr ""
|
||||
|
||||
#: src/ownership.md:1
|
||||
msgid "# Ownership"
|
||||
msgstr ""
|
||||
msgstr "# 所有权"
|
||||
|
||||
#: src/ownership.md:3
|
||||
msgid ""
|
||||
@ -4379,6 +4379,8 @@ msgid ""
|
||||
"to\n"
|
||||
"use a variable outside its scope:"
|
||||
msgstr ""
|
||||
"所有变量绑定都有一个有效的“作用域”,使用\n"
|
||||
"超出其作用域的变量是错误的:"
|
||||
|
||||
#: src/ownership.md:6
|
||||
msgid ""
|
||||
@ -4394,6 +4396,17 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable,compile_fail\n"
|
||||
"struct Point(i32, i32);\n"
|
||||
"\n"
|
||||
"fn main() {\n"
|
||||
" {\n"
|
||||
" let p = Point(3, 4);\n"
|
||||
" println!(\"x: {}\", p.0);\n"
|
||||
" }\n"
|
||||
" println!(\"y: {}\", p.1);\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership.md:18
|
||||
msgid ""
|
||||
@ -4401,14 +4414,17 @@ msgid ""
|
||||
"* A destructor can run here to free up resources.\n"
|
||||
"* We say that the variable _owns_ the value."
|
||||
msgstr ""
|
||||
"* 作用域结束时,变量会“被丢弃”,数据会被释放。\n"
|
||||
"* 析构函数可在此运行以释放资源。\n"
|
||||
"* 指出变量“拥有”值。"
|
||||
|
||||
#: src/ownership/move-semantics.md:1
|
||||
msgid "# Move Semantics"
|
||||
msgstr ""
|
||||
msgstr "# 移动语义"
|
||||
|
||||
#: src/ownership/move-semantics.md:3
|
||||
msgid "An assignment will transfer ownership between variables:"
|
||||
msgstr ""
|
||||
msgstr "赋值操作将在变量之间转移所有权:"
|
||||
|
||||
#: src/ownership/move-semantics.md:5
|
||||
msgid ""
|
||||
@ -4421,6 +4437,14 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable\n"
|
||||
"fn main() {\n"
|
||||
" let s1: String = String::from(\"Hello!\");\n"
|
||||
" let s2: String = s1;\n"
|
||||
" println!(\"s2: {s2}\");\n"
|
||||
" // println!(\"s1: {s1}\");\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/move-semantics.md:14
|
||||
msgid ""
|
||||
@ -4430,6 +4454,11 @@ msgid ""
|
||||
"* When `s2` goes out of scope, the string data is freed.\n"
|
||||
"* There is always _exactly_ one variable binding which owns a value."
|
||||
msgstr ""
|
||||
"* 将 `s1` 赋值给 `s2`,即转移了所有权。\n"
|
||||
"* 数据从 `s1`“移出”,且 `s1` 不再可供访问。\n"
|
||||
"* 当 `s1` 离开作用域时,什么都不会发生:它没有所有权。\n"
|
||||
"* 当 `s2` 离开作用域时,字符串数据被释放。\n"
|
||||
"* 变量绑定在任一时刻有且“只有”一个值。"
|
||||
|
||||
#: src/ownership/move-semantics.md:22
|
||||
msgid ""
|
||||
@ -4438,10 +4467,14 @@ msgid ""
|
||||
"\n"
|
||||
"* In Rust, clones are explicit (by using `clone`)."
|
||||
msgstr ""
|
||||
"* 指出这与 C++ 中的默认值相反。除非你使用 `std::move`(并已定义 move 构造函"
|
||||
"数!),否则 C++ 中的默认值是按值复制的。\n"
|
||||
"\n"
|
||||
"* 在 Rust 中,克隆是显式的(通过使用 `clone`)。"
|
||||
|
||||
#: src/ownership/moved-strings-rust.md:1
|
||||
msgid "# Moved Strings in Rust"
|
||||
msgstr ""
|
||||
msgstr "# Rust 中移动的字符串"
|
||||
|
||||
#: src/ownership/moved-strings-rust.md:3
|
||||
msgid ""
|
||||
@ -4452,16 +4485,24 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable\n"
|
||||
"fn main() {\n"
|
||||
" let s1: String = String::from(\"Rust\");\n"
|
||||
" let s2: String = s1;\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/moved-strings-rust.md:10
|
||||
msgid ""
|
||||
"* The heap data from `s1` is reused for `s2`.\n"
|
||||
"* When `s1` goes out of scope, nothing happens (it has been moved from)."
|
||||
msgstr ""
|
||||
"* `s1` 中的堆数据会被 `s2` 重复使用。\n"
|
||||
"* 当 `s1` 离开作用域时,什么都不会发生(它已被移出)。"
|
||||
|
||||
#: src/ownership/moved-strings-rust.md:13
|
||||
msgid "Before move to `s2`:"
|
||||
msgstr ""
|
||||
msgstr "移动到 `s2` 中之前:"
|
||||
|
||||
#: src/ownership/moved-strings-rust.md:15
|
||||
msgid ""
|
||||
@ -4480,10 +4521,24 @@ msgid ""
|
||||
"`- - - - - - - - - - - - - -'\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```bob\n"
|
||||
" 栈 堆\n"
|
||||
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n"
|
||||
": : : :\n"
|
||||
": s1 : : :\n"
|
||||
": +-----------+-------+ : : +----+----+----+----+ :\n"
|
||||
": | ptr | o---+---+-----+-->| R | u | s | t | :\n"
|
||||
": | len | 4 | : : +----+----+----+----+ :\n"
|
||||
": | capacity | 4 | : : :\n"
|
||||
": +-----------+-------+ : : :\n"
|
||||
": : `- - - - - - - - - - - - - -'\n"
|
||||
": :\n"
|
||||
"`- - - - - - - - - - - - - -'\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/moved-strings-rust.md:30
|
||||
msgid "After move to `s2`:"
|
||||
msgstr ""
|
||||
msgstr "移动到 `s2` 中之后:"
|
||||
|
||||
#: src/ownership/moved-strings-rust.md:32
|
||||
msgid ""
|
||||
@ -4508,14 +4563,34 @@ msgid ""
|
||||
"`- - - - - - - - - - - - - -'\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```bob\n"
|
||||
" 栈 堆\n"
|
||||
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n"
|
||||
": : : :\n"
|
||||
": s1 \"(无法访问)\" : : :\n"
|
||||
": +-----------+-------+ : : +----+----+----+----+ :\n"
|
||||
": | ptr | o---+---+--+--+-->| R | u | s | t | :\n"
|
||||
": | len | 4 | : | : +----+----+----+----+ :\n"
|
||||
": | capacity | 4 | : | : :\n"
|
||||
": +-----------+-------+ : | : :\n"
|
||||
": : | `- - - - - - - - - - - - - -'\n"
|
||||
": s2 : |\n"
|
||||
": +-----------+-------+ : |\n"
|
||||
": | ptr | o---+---+--'\n"
|
||||
": | len | 4 | :\n"
|
||||
": | capacity | 4 | :\n"
|
||||
": +-----------+-------+ :\n"
|
||||
": :\n"
|
||||
"`- - - - - - - - - - - - - -'\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/double-free-modern-cpp.md:1
|
||||
msgid "# Double Frees in Modern C++"
|
||||
msgstr ""
|
||||
msgstr "# 现代 C++ 中的双重释放"
|
||||
|
||||
#: src/ownership/double-free-modern-cpp.md:3
|
||||
msgid "Modern C++ solves this differently:"
|
||||
msgstr ""
|
||||
msgstr "现代 C++ 以不同的方式解决此问题:"
|
||||
|
||||
#: src/ownership/double-free-modern-cpp.md:5
|
||||
msgid ""
|
||||
@ -4524,6 +4599,10 @@ msgid ""
|
||||
"std::string s2 = s1; // Duplicate the data in s1.\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```c++\n"
|
||||
"std::string s1 = \"Cpp\";\n"
|
||||
"std::string s2 = s1; // 复制 s1 中的数据。\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/double-free-modern-cpp.md:10
|
||||
msgid ""
|
||||
@ -4531,10 +4610,12 @@ msgid ""
|
||||
"copy.\n"
|
||||
"* When `s1` and `s2` go out of scope, they each free their own memory."
|
||||
msgstr ""
|
||||
"* `s1` 中的堆数据被复制,`s2` 获得自己的独立副本。\n"
|
||||
"* 当 `s1` 和 `s2` 离开作用域时,它们会各自释放自己的内存。"
|
||||
|
||||
#: src/ownership/double-free-modern-cpp.md:13
|
||||
msgid "Before copy-assignment:"
|
||||
msgstr ""
|
||||
msgstr "复制-赋值之前:"
|
||||
|
||||
#: src/ownership/double-free-modern-cpp.md:16
|
||||
msgid ""
|
||||
@ -4552,10 +4633,23 @@ msgid ""
|
||||
"`- - - - - - - - - - - - - -'\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```bob\n"
|
||||
" 栈 堆\n"
|
||||
".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
|
||||
": : : :\n"
|
||||
": s1 : : :\n"
|
||||
": +-----------+-------+ : : +----+----+----+ :\n"
|
||||
": | ptr | o---+---+--+--+-->| C | p | p | :\n"
|
||||
": | len | 3 | : : +----+----+----+ :\n"
|
||||
": | capacity | 3 | : : :\n"
|
||||
": +-----------+-------+ : : :\n"
|
||||
": : `- - - - - - - - - - - -'\n"
|
||||
"`- - - - - - - - - - - - - -'\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/double-free-modern-cpp.md:30
|
||||
msgid "After copy-assignment:"
|
||||
msgstr ""
|
||||
msgstr "复制-赋值之后:"
|
||||
|
||||
#: src/ownership/double-free-modern-cpp.md:32
|
||||
msgid ""
|
||||
@ -4580,16 +4674,38 @@ msgid ""
|
||||
"`- - - - - - - - - - - - - -'\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```bob\n"
|
||||
" 栈 堆\n"
|
||||
".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
|
||||
": : : :\n"
|
||||
": s1 : : :\n"
|
||||
": +-----------+-------+ : : +----+----+----+ :\n"
|
||||
": | ptr | o---+---+--+--+-->| C | p | p | :\n"
|
||||
": | len | 3 | : : +----+----+----+ :\n"
|
||||
": | capacity | 3 | : : :\n"
|
||||
": +-----------+-------+ : : :\n"
|
||||
": : : :\n"
|
||||
": s2 : : :\n"
|
||||
": +-----------+-------+ : : +----+----+----+ :\n"
|
||||
": | ptr | o---+---+-----+-->| C | p | p | :\n"
|
||||
": | len | 3 | : : +----+----+----+ :\n"
|
||||
": | capacity | 3 | : : :\n"
|
||||
": +-----------+-------+ : : :\n"
|
||||
": : `- - - - - - - - - - - -'\n"
|
||||
"`- - - - - - - - - - - - - -'\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/moves-function-calls.md:1
|
||||
msgid "# Moves in Function Calls"
|
||||
msgstr ""
|
||||
msgstr "# 函数调用中的移动"
|
||||
|
||||
#: src/ownership/moves-function-calls.md:3
|
||||
msgid ""
|
||||
"When you pass a value to a function, the value is assigned to the function\n"
|
||||
"parameter. This transfers ownership:"
|
||||
msgstr ""
|
||||
"你将值传递给函数时,该值会被赋给函数\n"
|
||||
"参数。这就转移了所有权:"
|
||||
|
||||
#: src/ownership/moves-function-calls.md:6
|
||||
msgid ""
|
||||
@ -4605,6 +4721,17 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable\n"
|
||||
"fn say_hello(name: String) {\n"
|
||||
" println!(\"Hello {name}\")\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"fn main() {\n"
|
||||
" let name = String::from(\"Alice\");\n"
|
||||
" say_hello(name);\n"
|
||||
" // say_hello(name);\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/moves-function-calls.md:20
|
||||
msgid ""
|
||||
@ -4620,15 +4747,23 @@ msgid ""
|
||||
"move semantics the default, and by forcing programmers to make clones "
|
||||
"explicit."
|
||||
msgstr ""
|
||||
"* 首次调用 `say_hello` 时,`main` 便放弃了 `name` 的所有权。此后,`main` 中不"
|
||||
"能再使用 `name`。\n"
|
||||
"* 在 `say_hello` 函数结束时,系统会释放为 `name` 分配的堆内存。\n"
|
||||
"* 如果 `main` 将 `name` 作为引用 (`&name`) 传递过去,且 `say_hello` 接受作为"
|
||||
"参数的引用,则可保留所有权。\n"
|
||||
"* 此外,`main` 也可以在首次调用时传递 `name` 的克隆 (`name.clone()`)。\n"
|
||||
"* 相较于 C++,Rust 通过将移动语义设为默认值,并强制程序员进行显式克隆,更难以"
|
||||
"无意中创建副本。"
|
||||
|
||||
#: src/ownership/copy-clone.md:1
|
||||
msgid "# Copying and Cloning"
|
||||
msgstr ""
|
||||
msgstr "# 复制和克隆"
|
||||
|
||||
#: src/ownership/copy-clone.md:3
|
||||
msgid ""
|
||||
"While move semantics are the default, certain types are copied by default:"
|
||||
msgstr ""
|
||||
msgstr "虽然移动语义是默认的,但默认情况下会复制某些类型:"
|
||||
|
||||
#: src/ownership/copy-clone.md:5
|
||||
msgid ""
|
||||
@ -4641,14 +4776,22 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable\n"
|
||||
"fn main() {\n"
|
||||
" let x = 42;\n"
|
||||
" let y = x;\n"
|
||||
" println!(\"x: {x}\");\n"
|
||||
" println!(\"y: {y}\");\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/copy-clone.md:14
|
||||
msgid "These types implement the `Copy` trait."
|
||||
msgstr ""
|
||||
msgstr "这些类型实现了 `Copy` trait。"
|
||||
|
||||
#: src/ownership/copy-clone.md:16
|
||||
msgid "You can opt-in your own types to use copy semantics:"
|
||||
msgstr ""
|
||||
msgstr "你可以选择自己的类型来使用复制语义:"
|
||||
|
||||
#: src/ownership/copy-clone.md:18
|
||||
msgid ""
|
||||
@ -4664,16 +4807,29 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable\n"
|
||||
"#[derive(Copy, Clone, Debug)]\n"
|
||||
"struct Point(i32, i32);\n"
|
||||
"\n"
|
||||
"fn main() {\n"
|
||||
" let p1 = Point(3, 4);\n"
|
||||
" let p2 = p1;\n"
|
||||
" println!(\"p1: {p1:?}\");\n"
|
||||
" println!(\"p2: {p2:?}\");\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/copy-clone.md:30
|
||||
msgid ""
|
||||
"* After the assignment, both `p1` and `p2` own their own data.\n"
|
||||
"* We can also use `p1.clone()` to explicitly copy the data."
|
||||
msgstr ""
|
||||
"* 赋值之后,`p1` 和 `p2` 都拥有自己的数据。\n"
|
||||
"* 我们还可以使用 `p1.clone()` 显式复制数据。"
|
||||
|
||||
#: src/ownership/copy-clone.md:35
|
||||
msgid "Copying and cloning are not the same thing:"
|
||||
msgstr ""
|
||||
msgstr "复制和克隆是两码事:"
|
||||
|
||||
#: src/ownership/copy-clone.md:37
|
||||
msgid ""
|
||||
@ -4685,10 +4841,14 @@ msgid ""
|
||||
"implementing the `Clone` trait.\n"
|
||||
"* Copying does not work on types that implement the `Drop` trait."
|
||||
msgstr ""
|
||||
"* 复制是指内存区域的按位复制,不适用于任意对象。\n"
|
||||
"* 复制不允许自定义逻辑(不同于 C++ 中的复制构造函数)。\n"
|
||||
"* 克隆是一种更通用的操作,也允许通过实现 `Clone` trait 来自定义行为。\n"
|
||||
"* 复制不适用于实现 `Drop` trait 的类型。"
|
||||
|
||||
#: src/ownership/copy-clone.md:42 src/ownership/lifetimes-function-calls.md:29
|
||||
msgid "In the above example, try the following:"
|
||||
msgstr ""
|
||||
msgstr "在上述示例中,请尝试以下操作:"
|
||||
|
||||
#: src/ownership/copy-clone.md:44
|
||||
msgid ""
|
||||
@ -4698,6 +4858,11 @@ msgid ""
|
||||
"the `println!` for `p1`.\n"
|
||||
"* Show that it works if you clone `p1` instead."
|
||||
msgstr ""
|
||||
"* 在 `struct Point` 中添加 `String` 字段。由于 `String` 不属于 `Copy` 类型,"
|
||||
"因此无法编译。\n"
|
||||
"* 从 `derive` 属性中移除 `Copy`。现在,编译器错误位于 `p1`的 `println!` "
|
||||
"中。\n"
|
||||
"* 指出如果你改为克隆 `p1`,则可按预期运行。"
|
||||
|
||||
#: src/ownership/copy-clone.md:48
|
||||
msgid ""
|
||||
@ -4706,16 +4871,21 @@ msgid ""
|
||||
"at compile time. In this case the default implementations of `Copy` and "
|
||||
"`Clone` traits are generated."
|
||||
msgstr ""
|
||||
"如果学员问起 `derive`,只需说这是一种\n"
|
||||
"在编译时生成 Rust 代码的方法。在这种情况下,系统会生成 `Copy` 和 `Clone` "
|
||||
"trait 的默认实现。"
|
||||
|
||||
#: src/ownership/borrowing.md:1
|
||||
msgid "# Borrowing"
|
||||
msgstr ""
|
||||
msgstr "# 借用"
|
||||
|
||||
#: src/ownership/borrowing.md:3
|
||||
msgid ""
|
||||
"Instead of transferring ownership when calling a function, you can let a\n"
|
||||
"function _borrow_ the value:"
|
||||
msgstr ""
|
||||
"调用函数时,你可以让\n"
|
||||
"函数“借用”值,而不是转移所有权:"
|
||||
|
||||
#: src/ownership/borrowing.md:6
|
||||
msgid ""
|
||||
@ -4735,16 +4905,33 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable\n"
|
||||
"#[derive(Debug)]\n"
|
||||
"struct Point(i32, i32);\n"
|
||||
"\n"
|
||||
"fn add(p1: &Point, p2: &Point) -> Point {\n"
|
||||
" Point(p1.0 + p2.0, p1.1 + p2.1)\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"fn main() {\n"
|
||||
" let p1 = Point(3, 4);\n"
|
||||
" let p2 = Point(10, 20);\n"
|
||||
" let p3 = add(&p1, &p2);\n"
|
||||
" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/borrowing.md:22
|
||||
msgid ""
|
||||
"* The `add` function _borrows_ two points and returns a new point.\n"
|
||||
"* The caller retains ownership of the inputs."
|
||||
msgstr ""
|
||||
"* `add` 函数“借用”两个点并返回一个新点。\n"
|
||||
"* 调用方会保留输入的所有权。"
|
||||
|
||||
#: src/ownership/borrowing.md:27
|
||||
msgid "Notes on stack returns:"
|
||||
msgstr ""
|
||||
msgstr "关于栈返回的说明:"
|
||||
|
||||
#: src/ownership/borrowing.md:28
|
||||
msgid ""
|
||||
@ -4778,20 +4965,48 @@ msgid ""
|
||||
"all. If RVO did not happen, Rust will always performs a simple and efficient "
|
||||
"`memcpy` copy."
|
||||
msgstr ""
|
||||
"* 证明从 `add` 返回的开销很低,因为编译器可以消除复制操作。更改上述代码以输出"
|
||||
"栈地址,并在 [Playground] 上运行它。在“调试”优化级别中,地址应发生变化,而在"
|
||||
"改成“发布”设置时保持不变:\n"
|
||||
"\n"
|
||||
" ```rust,editable\n"
|
||||
" #[derive(Debug)]\n"
|
||||
" struct Point(i32, i32);\n"
|
||||
"\n"
|
||||
" fn add(p1: &Point, p2: &Point) -> Point {\n"
|
||||
" let p = Point(p1.0 + p2.0, p1.1 + p2.1);\n"
|
||||
" println!(\"&p.0: {:p}\", &p.0);\n"
|
||||
" p\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" fn main() {\n"
|
||||
" let p1 = Point(3, 4);\n"
|
||||
" let p2 = Point(10, 20);\n"
|
||||
" let p3 = add(&p1, &p2);\n"
|
||||
" println!(\"&p3.0: {:p}\", &p3.0);\n"
|
||||
" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n"
|
||||
" }\n"
|
||||
" ```\n"
|
||||
"* Rust 编译器能够执行返回值优化 (RVO)。\n"
|
||||
"* 在 C++ 中,必须在语言规范中定义复制省略,因为构造函数可能会有附带效应。在 "
|
||||
"Rust 中,这完全不是问题。如果 RVO 未发生,Rust 将始终执行简单且高效的 "
|
||||
"`memcpy` 复制。"
|
||||
|
||||
#: src/ownership/shared-unique-borrows.md:1
|
||||
msgid "# Shared and Unique Borrows"
|
||||
msgstr ""
|
||||
msgstr "# 共享和唯一的借用"
|
||||
|
||||
#: src/ownership/shared-unique-borrows.md:3
|
||||
msgid "Rust puts constraints on the ways you can borrow values:"
|
||||
msgstr ""
|
||||
msgstr "Rust 限制了借用值的方式:"
|
||||
|
||||
#: src/ownership/shared-unique-borrows.md:5
|
||||
msgid ""
|
||||
"* You can have one or more `&T` values at any given time, _or_\n"
|
||||
"* You can have exactly one `&mut T` value."
|
||||
msgstr ""
|
||||
"* 在任何给定时间,你都可以有一个或多个 `&T` 值,或者\n"
|
||||
"* 你可以有且只有一个 `&mut T` 值。"
|
||||
|
||||
#: src/ownership/shared-unique-borrows.md:8
|
||||
msgid ""
|
||||
@ -4810,6 +5025,20 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable,compile_fail\n"
|
||||
"fn main() {\n"
|
||||
" let mut a: i32 = 10;\n"
|
||||
" let b: &i32 = &a;\n"
|
||||
"\n"
|
||||
" {\n"
|
||||
" let c: &mut i32 = &mut a;\n"
|
||||
" *c = 20;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" println!(\"a: {a}\");\n"
|
||||
" println!(\"b: {b}\");\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/shared-unique-borrows.md:25
|
||||
msgid ""
|
||||
@ -4821,14 +5050,19 @@ msgid ""
|
||||
"the new mutable borrow of `a` through `c`. This is a feature of the borrow "
|
||||
"checker called \"non-lexical lifetimes\"."
|
||||
msgstr ""
|
||||
"* 上述代码无法编译,因为 `a` 同时作为可变值(通过 `c`)和不可变值(通过 `b`)"
|
||||
"被借用。\n"
|
||||
"* 将`b` 的 `println!` 语句移到引入 `c` 的作用域之前,这段代码就可以编译。\n"
|
||||
"* 这样更改后,编译器会发现 `b` 只在通过 `c` 对 `a` 进行新可变借用之前使用过。"
|
||||
"这是借用检查器的一个功能,名为“非词法作用域生命周期”。"
|
||||
|
||||
#: src/ownership/lifetimes.md:1
|
||||
msgid "# Lifetimes"
|
||||
msgstr ""
|
||||
msgstr "# 生命周期"
|
||||
|
||||
#: src/ownership/lifetimes.md:3
|
||||
msgid "A borrowed value has a _lifetime_:"
|
||||
msgstr ""
|
||||
msgstr "借用的值是有“生命周期”的:"
|
||||
|
||||
#: src/ownership/lifetimes.md:5
|
||||
msgid ""
|
||||
@ -4850,13 +5084,13 @@ msgstr ""
|
||||
|
||||
#: src/ownership/lifetimes-function-calls.md:1
|
||||
msgid "# Lifetimes in Function Calls"
|
||||
msgstr ""
|
||||
msgstr "# 函数调用中的生命周期"
|
||||
|
||||
#: src/ownership/lifetimes-function-calls.md:3
|
||||
msgid ""
|
||||
"In addition to borrowing its arguments, a function can return a borrowed "
|
||||
"value:"
|
||||
msgstr ""
|
||||
msgstr "除了借用其参数之外,函数还可以返回借用的值:"
|
||||
|
||||
#: src/ownership/lifetimes-function-calls.md:5
|
||||
msgid ""
|
||||
@ -4876,6 +5110,21 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable\n"
|
||||
"#[derive(Debug)]\n"
|
||||
"struct Point(i32, i32);\n"
|
||||
"\n"
|
||||
"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
|
||||
" if p1.0 < p2.0 { p1 } else { p2 }\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"fn main() {\n"
|
||||
" let p1: Point = Point(10, 10);\n"
|
||||
" let p2: Point = Point(20, 20);\n"
|
||||
" let p3: &Point = left_most(&p1, &p2);\n"
|
||||
" println!(\"left-most point: {:?}\", p3);\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/lifetimes-function-calls.md:21
|
||||
msgid ""
|
||||
@ -4885,6 +5134,11 @@ msgid ""
|
||||
" lifetime `a`\".\n"
|
||||
" * The _at least_ part is important when parameters are in different scopes."
|
||||
msgstr ""
|
||||
"* `'a` 是一个泛型形参,由编译器推断出来。\n"
|
||||
"* 以 `'` 和 `'a` 开头的生命周期是典型的默认名称。\n"
|
||||
"* 将 `&'a Point` 读取为“借用的 `Point,至少\n"
|
||||
"在 `a` 生命周期内有效。\n"
|
||||
" * 当参数在不同的作用域时,“至少”部分至关重要。"
|
||||
|
||||
#: src/ownership/lifetimes-function-calls.md:31
|
||||
msgid ""
|
||||
@ -4926,12 +5180,12 @@ msgstr ""
|
||||
|
||||
#: src/ownership/lifetimes-data-structures.md:1
|
||||
msgid "# Lifetimes in Data Structures"
|
||||
msgstr ""
|
||||
msgstr "# 数据结构中的生命周期"
|
||||
|
||||
#: src/ownership/lifetimes-data-structures.md:3
|
||||
msgid ""
|
||||
"If a data type stores borrowed data, it must be annotated with a lifetime:"
|
||||
msgstr ""
|
||||
msgstr "如果数据类型存储了借用的数据,则必须对其添加生命周期注释:"
|
||||
|
||||
#: src/ownership/lifetimes-data-structures.md:5
|
||||
msgid ""
|
||||
@ -4954,6 +5208,24 @@ msgid ""
|
||||
"}\n"
|
||||
"```"
|
||||
msgstr ""
|
||||
"```rust,editable\n"
|
||||
"#[derive(Debug)]\n"
|
||||
"struct Highlight<'doc>(&'doc str);\n"
|
||||
"\n"
|
||||
"fn erase(text: String) {\n"
|
||||
" println!(\"Bye {text}!\");\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"fn main() {\n"
|
||||
" let text = String::from(\"The quick brown fox jumps over the lazy dog."
|
||||
"\");\n"
|
||||
" let fox = Highlight(&text[4..19]);\n"
|
||||
" let dog = Highlight(&text[35..43]);\n"
|
||||
" // erase(text);\n"
|
||||
" println!(\"{fox:?}\");\n"
|
||||
" println!(\"{dog:?}\");\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/lifetimes-data-structures.md:25
|
||||
msgid ""
|
||||
@ -4971,6 +5243,16 @@ msgid ""
|
||||
"lifetime relationships between the references themselves, in addition to the "
|
||||
"lifetime of the struct itself. Those are very advanced use cases."
|
||||
msgstr ""
|
||||
"* 在上述示例中,`Highlight` 注释会强制包含 `&str` 的底层数据的生命周期至少与"
|
||||
"使用该数据的任何 `Highlight` 实例一样长。\n"
|
||||
"* 如果 `text` 在 `fox`(或 `dog`)的生命周期结束前被消耗,借用检查器将抛出一"
|
||||
"个错误。\n"
|
||||
"* 借用数据的类型会迫使用户保留原始数据。这对于创建轻量级视图很有用,但通常会"
|
||||
"使它们更难使用。\n"
|
||||
"* 如有可能,让数据结构直接拥有自己的数据。\n"
|
||||
"* 一些包含多个引用的结构可以有多个生命周期注释。除了结构体本身的生命周期之"
|
||||
"外,如果需要描述引用之间的生命周期关系,则可能需要这样做。这些都是非常高级的"
|
||||
"用例。"
|
||||
|
||||
#: src/exercises/day-1/afternoon.md:1
|
||||
msgid "# Day 1: Afternoon Exercises"
|
||||
@ -20000,3 +20282,100 @@ msgstr ""
|
||||
" println!(\"You got: {:?}\", flip_coin());\n"
|
||||
"}\n"
|
||||
"```"
|
||||
|
||||
#: src/ownership/lifetimes.md:5
|
||||
msgid ""
|
||||
"* The lifetime can be implicit: `add(p1: &Point, p2: &Point) -> Point`.\n"
|
||||
"* Lifetimes can also be explicit: `&'a Point`, `&'document str`.\n"
|
||||
"* Read `&'a Point` as \"a borrowed `Point` which is valid for at least the\n"
|
||||
" lifetime `a`\".\n"
|
||||
"* Lifetimes are always inferred by the compiler: you cannot assign a "
|
||||
"lifetime\n"
|
||||
" yourself.\n"
|
||||
" * Lifetime annotations create constraints; the compiler verifies that "
|
||||
"there is\n"
|
||||
" a valid solution.\n"
|
||||
"* Lifetimes for function arguments and return values must be fully "
|
||||
"specified,\n"
|
||||
" but Rust allows these to be elided in most cases with [a few simple\n"
|
||||
" rules](https://doc.rust-lang.org/nomicon/lifetime-elision.html)."
|
||||
msgstr ""
|
||||
"* 生命周期可以是隐式的:add(p1: &Point, p2: &Point) -> Point`。\n"
|
||||
"* 生命周期也可以是显式的:`&'a Point`、`&'document str`。\n"
|
||||
"* 将 `&'a Point` 读取为“一个借用的 `Point`,至少在\n"
|
||||
"生命周期 `a` 内有效”。\n"
|
||||
"* 生命周期始终由编译器推断出来:你不能自行\n"
|
||||
"分配生命周期。\n"
|
||||
" * 生命周期注释会创建约束条件;编译器会验证\n"
|
||||
"是否存在有效的解决方案。\n"
|
||||
"* 必须完全指定函数参数和返回值的生命周期,\n"
|
||||
"但 Rust 允许在大多数情况下通过[一些简单的\n"
|
||||
"规则](https://doc.rust-lang.org/nomicon/lifetime-elision.html)来省略此操作。"
|
||||
|
||||
#: src/ownership/lifetimes-function-calls.md:31
|
||||
msgid ""
|
||||
"* Move the declaration of `p2` and `p3` into a new scope (`{ ... }`), "
|
||||
"resulting in the following code:\n"
|
||||
" ```rust,ignore\n"
|
||||
" #[derive(Debug)]\n"
|
||||
" struct Point(i32, i32);\n"
|
||||
"\n"
|
||||
" fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
|
||||
" if p1.0 < p2.0 { p1 } else { p2 }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" fn main() {\n"
|
||||
" let p1: Point = Point(10, 10);\n"
|
||||
" let p3: &Point;\n"
|
||||
" {\n"
|
||||
" let p2: Point = Point(20, 20);\n"
|
||||
" p3 = left_most(&p1, &p2);\n"
|
||||
" }\n"
|
||||
" println!(\"left-most point: {:?}\", p3);\n"
|
||||
" }\n"
|
||||
" ```\n"
|
||||
" Note how this does not compile since `p3` outlives `p2`.\n"
|
||||
"\n"
|
||||
"* Reset the workspace and change the function signature to `fn left_most<'a, "
|
||||
"'b>(p1: &'a Point, p2: &'a Point) -> &'b Point`. This will not compile "
|
||||
"because the relationship between the lifetimes `'a` and `'b` is unclear.\n"
|
||||
"* Another way to explain it:\n"
|
||||
" * Two references to two values are borrowed by a function and the function "
|
||||
"returns\n"
|
||||
" another reference.\n"
|
||||
" * It must have come from one of those two inputs (or from a global "
|
||||
"variable).\n"
|
||||
" * Which one is it? The compiler needs to know, so at the call site the "
|
||||
"returned reference is not used\n"
|
||||
" for longer than a variable from where the reference came from."
|
||||
msgstr ""
|
||||
"* 将 `p2` 和 `p3` 的声明移至新作用域 (`{ ... }`),以产生以下代码:\n"
|
||||
" ```rust,ignore\n"
|
||||
" #[derive(Debug)]\n"
|
||||
" struct Point(i32, i32);\n"
|
||||
"\n"
|
||||
" fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
|
||||
" if p1.0 < p2.0 { p1 } else { p2 }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" fn main() {\n"
|
||||
" let p1: Point = Point(10, 10);\n"
|
||||
" let p3: &Point;\n"
|
||||
" {\n"
|
||||
" let p2: Point = Point(20, 20);\n"
|
||||
" p3 = left_most(&p1, &p2);\n"
|
||||
" }\n"
|
||||
" println!(\"left-most point: {:?}\", p3);\n"
|
||||
" }\n"
|
||||
" ```\n"
|
||||
" 请注意:由于 `p3` 的生命周期比 `p2` 长,因此无法编译。\n"
|
||||
"\n"
|
||||
"* 重置工作区,然后将函数签名更改为 `fn left_most<'a, 'b>(p1: &'a Point, p2: "
|
||||
"&'a Point) -> &'b Point`。这不会被编译,因为 `'a` 和 `'b` 生命周期之间的关系"
|
||||
"不明确。\n"
|
||||
"* 另一种解释方式:\n"
|
||||
" * 对两个值的两个引用被一个函数借用,该函数返回\n"
|
||||
"另一个引用。\n"
|
||||
" * 它必须是来自这两个输入中的一个(或来自一个全局变量)。\n"
|
||||
" * 是哪一个呢?编译器需要知道这一点,因此在调用点,返回的引用\n"
|
||||
"的使用时间不会超过引用的来源中的变量。"
|
||||
|
Loading…
x
Reference in New Issue
Block a user