From 2ef9ed69ed0d7fb20f1361d0583961fe4f039865 Mon Sep 17 00:00:00 2001 From: chenxuuu Date: Tue, 11 Jan 2022 16:05:55 +0800 Subject: [PATCH 01/10] =?UTF-8?q?fix:=20```=E6=98=BE=E7=A4=BA=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- book/contents/advance/comment.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/book/contents/advance/comment.md b/book/contents/advance/comment.md index 01ac52f9..bf2c6355 100644 --- a/book/contents/advance/comment.md +++ b/book/contents/advance/comment.md @@ -84,22 +84,22 @@ pub fn add_one(x: i32) -> i32 { #### 文档块注释`/** ... */` 与代码注释一样,文档也有块注释,当注释内容多时,可以减少`///`的使用: -```rust +````rust /** `add_two`将指定值加2. # Examples -\`\`\` +``` let arg = 5; let answer = my_crate::add_two(arg); assert_eq!(7, answer); -\`\`\` +``` */ pub fn add_two(x: i32) -> i32 { x + 2 } -``` +```` #### 查看文档cargo doc 锦衣不夜行,这是中国人的传统美德。我们写了这么漂亮的文档注释,当然要看看网页中是什么效果咯。 From c12f18b9c9c74a129905c8b87c3f9cbeb3a848a7 Mon Sep 17 00:00:00 2001 From: chenxuuu Date: Tue, 11 Jan 2022 17:49:18 +0800 Subject: [PATCH 02/10] fix: Boxt -> Box --- book/contents/advance/smart-pointer/box.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/contents/advance/smart-pointer/box.md b/book/contents/advance/smart-pointer/box.md index 140be256..6a6e4574 100644 --- a/book/contents/advance/smart-pointer/box.md +++ b/book/contents/advance/smart-pointer/box.md @@ -45,7 +45,7 @@ fn foo(x: &str) -> String { 以上场景,我们在本章将一一讲解,后面车速较快,请系好安全带。 #### 使用`Box`将数据存储在堆上 -如果一个变量拥有一个数值`let a = 3`, 那变量`a`必然是存储在栈上的,那如果我们想要`a`的值存储在堆上就需要使用`Boxt`: +如果一个变量拥有一个数值`let a = 3`, 那变量`a`必然是存储在栈上的,那如果我们想要`a`的值存储在堆上就需要使用`Box`: ```rust fn main() { let a = Box::new(3); @@ -114,7 +114,7 @@ error[E0072]: recursive type `List` has infinite size //递归类型`List`拥有 | ---- recursive without indirection ``` -此时若想解决这个问题,就可以使用我们的`Boxt`: +此时若想解决这个问题,就可以使用我们的`Box`: ```rust enum List { Cons(i32, Box), From 872b57eb53e791e0d78105eae3005e6e2606350f Mon Sep 17 00:00:00 2001 From: Jesse <35264598+JesseAtSZ@users.noreply.github.com> Date: Tue, 11 Jan 2022 19:23:47 +0800 Subject: [PATCH 03/10] Update intro.md --- book/contents/basic/compound-type/intro.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/book/contents/basic/compound-type/intro.md b/book/contents/basic/compound-type/intro.md index 0bd5a05f..418c7875 100644 --- a/book/contents/basic/compound-type/intro.md +++ b/book/contents/basic/compound-type/intro.md @@ -2,7 +2,7 @@ 行百里者半五十,欢迎大家来到这里,虽然还不到中点,但是已经不远了。如果说之前学的基础数据类型是原子,那么本章将讲的数据类型可以认为是分子。 -本章的重点在复合类型上,顾名思义,复合类型是由其它类型组合而来,最典型的就是结构体`struct`和枚举`enum`。例如一个2D的点`point(x,y)`,它从两个数值类型组合而来。我们不想单独去维护这两个数值,而是希望把它们看作一个整体去认识和处理。 +本章的重点在复合类型上,顾名思义,复合类型是由其它类型组合而成的,最典型的就是结构体`struct`和枚举`enum`。例如平面上的一个点`point(x,y)`,它由两个数值类型的值x和y组合而来。我们不想单独去维护这两个数值,因为单独一个x或者y是含义不完整的,不足以标识平面上的一个点,应该把它们看作一个整体去理解和处理。 来看一段代码,它使用我们之前学过的内容来构建文件操作: ```rust @@ -29,11 +29,11 @@ fn main() { } ``` - 当前阶段非常类似原型设计:提供api接口,但是不去实现它们。因此在这个阶段我们需要排除一些编译器噪音,引入了`#![allow(unused_variables)]`属性标记,该标记会告诉编译器无视未使用的变量,不要抛出`warning`警告,具体的常见编译器属性你可以在这里查阅:[编译器属性标记](../../compiler/attributes.md). +接下来我们的学习非常类似原型设计:有的方法只提供API接口,但是不提供具体实现。此外,有的变量在声明之后并未使用,因此在这个阶段我们需要排除一些编译器噪音(Rust在编译的时候会扫面代码,变量声明后未使用会以`warning`警告的形式进行提示),引入了`#![allow(unused_variables)]`属性标记,该标记会告诉编译器忽略未使用的变量,不要抛出`warning`警告,具体的常见编译器属性你可以在这里查阅:[编译器属性标记](../../compiler/attributes.md). - `read`函数也非常有趣,它返回一个`!`,这个表明该函数是一个发散函数,不会返回任何值,包括`()`。`unimplemented!()`告诉编译器该函数尚未实现,其实主要帮助我们快速完成主要代码,回头可以通过搜索这些标记来完成次要代码,类似的还有`todo!()`,当代码执行到这种未实现的地方时,程序会直接报错: 你可以反注释`read(&mut f1, &mut vec![]);`这行,然后再观察下结果。 + `read`函数也非常有趣,它返回一个`!`,这个表明该函数是一个发散函数,不会返回任何值,包括`()`。`unimplemented!()`告诉编译器该函数尚未实现,`unimplemented!()`标记通常意味着我们期望快速完成主要代码,回头再通过搜索这些标记来完成次要代码,类似的标记还有`todo!()`,当代码执行到这种未实现的地方时,程序会直接报错: 你可以反注释`read(&mut f1, &mut vec![]);`这行,然后再观察下结果。 - 同时,从代码设计角度来看,假如关于文件操作的类型和函数散落的到处都是,是难以管理和使用的。而且`open(&mut f1)`也远没有`f1.open()`好,因此这就是基本类型的局限性:**无法从更高的抽象层次去简化代码**。 + 同时,从代码设计角度来看,关于文件操作的类型和函数应该组织在一起,散落得到处都是,是难以管理和使用的。而且通过`open(&mut f1)`进行调用,也远没有使用`f1.open()`来调用好,这就体现出了只使用基本类型得局限性:**无法从更高的抽象层次去简化代码**。 -接下来,我们将引入一个高级数据结构 - 结构体`struct`,来看看怎么样更好的解决这类问题。 开始之前,先来看看何为`元组`. \ No newline at end of file +接下来,我们将引入一个高级数据结构 - 结构体`struct`,来看看结构体是怎样更好的解决这类问题。 开始之前,先来看看什么是`元组`. From 98d3f444468ae787c27aedbafeb73c7363ac0519 Mon Sep 17 00:00:00 2001 From: Jesse <35264598+JesseAtSZ@users.noreply.github.com> Date: Tue, 11 Jan 2022 19:26:03 +0800 Subject: [PATCH 04/10] Update intro.md --- book/contents/basic/compound-type/intro.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/contents/basic/compound-type/intro.md b/book/contents/basic/compound-type/intro.md index 418c7875..2bde1dbf 100644 --- a/book/contents/basic/compound-type/intro.md +++ b/book/contents/basic/compound-type/intro.md @@ -2,7 +2,7 @@ 行百里者半五十,欢迎大家来到这里,虽然还不到中点,但是已经不远了。如果说之前学的基础数据类型是原子,那么本章将讲的数据类型可以认为是分子。 -本章的重点在复合类型上,顾名思义,复合类型是由其它类型组合而成的,最典型的就是结构体`struct`和枚举`enum`。例如平面上的一个点`point(x,y)`,它由两个数值类型的值x和y组合而来。我们不想单独去维护这两个数值,因为单独一个x或者y是含义不完整的,不足以标识平面上的一个点,应该把它们看作一个整体去理解和处理。 +本章的重点在复合类型上,顾名思义,复合类型是由其它类型组合而成的,最典型的就是结构体`struct`和枚举`enum`。例如平面上的一个点`point(x,y)`,它由两个数值类型的值`x`和`y`组合而来。我们不想单独去维护这两个数值,因为单独一个`x`或者`y`是含义不完整的,无法标识平面上的一个点,应该把它们看作一个整体去理解和处理。 来看一段代码,它使用我们之前学过的内容来构建文件操作: ```rust @@ -29,7 +29,7 @@ fn main() { } ``` -接下来我们的学习非常类似原型设计:有的方法只提供API接口,但是不提供具体实现。此外,有的变量在声明之后并未使用,因此在这个阶段我们需要排除一些编译器噪音(Rust在编译的时候会扫面代码,变量声明后未使用会以`warning`警告的形式进行提示),引入了`#![allow(unused_variables)]`属性标记,该标记会告诉编译器忽略未使用的变量,不要抛出`warning`警告,具体的常见编译器属性你可以在这里查阅:[编译器属性标记](../../compiler/attributes.md). +接下来我们的学习非常类似原型设计:有的方法只提供API接口,但是不提供具体实现。此外,有的变量在声明之后并未使用,因此在这个阶段我们需要排除一些编译器噪音(Rust在编译的时候会扫描代码,变量声明后未使用会以`warning`警告的形式进行提示),引入`#![allow(unused_variables)]`属性标记,该标记会告诉编译器忽略未使用的变量,不要抛出`warning`警告,具体的常见编译器属性你可以在这里查阅:[编译器属性标记](../../compiler/attributes.md). `read`函数也非常有趣,它返回一个`!`,这个表明该函数是一个发散函数,不会返回任何值,包括`()`。`unimplemented!()`告诉编译器该函数尚未实现,`unimplemented!()`标记通常意味着我们期望快速完成主要代码,回头再通过搜索这些标记来完成次要代码,类似的标记还有`todo!()`,当代码执行到这种未实现的地方时,程序会直接报错: 你可以反注释`read(&mut f1, &mut vec![]);`这行,然后再观察下结果。 From fffc787096baad64e12934012c4aa6b6ea55b1f0 Mon Sep 17 00:00:00 2001 From: Jesse <35264598+JesseAtSZ@users.noreply.github.com> Date: Tue, 11 Jan 2022 19:27:08 +0800 Subject: [PATCH 05/10] Update intro.md --- book/contents/basic/compound-type/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/contents/basic/compound-type/intro.md b/book/contents/basic/compound-type/intro.md index 2bde1dbf..9deebfb1 100644 --- a/book/contents/basic/compound-type/intro.md +++ b/book/contents/basic/compound-type/intro.md @@ -36,4 +36,4 @@ fn main() { 同时,从代码设计角度来看,关于文件操作的类型和函数应该组织在一起,散落得到处都是,是难以管理和使用的。而且通过`open(&mut f1)`进行调用,也远没有使用`f1.open()`来调用好,这就体现出了只使用基本类型得局限性:**无法从更高的抽象层次去简化代码**。 -接下来,我们将引入一个高级数据结构 - 结构体`struct`,来看看结构体是怎样更好的解决这类问题。 开始之前,先来看看什么是`元组`. +接下来,我们将引入一个高级数据结构 - 结构体`struct`,来看看复合类型是怎样更好的解决这类问题。 开始之前,先来看看什么是`元组`. From 817c72147b6a406028d0fae5d1a549a67104ed3c Mon Sep 17 00:00:00 2001 From: Jesse <35264598+JesseAtSZ@users.noreply.github.com> Date: Tue, 11 Jan 2022 19:56:39 +0800 Subject: [PATCH 06/10] Update string-slice.md --- book/contents/basic/compound-type/string-slice.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/book/contents/basic/compound-type/string-slice.md b/book/contents/basic/compound-type/string-slice.md index 27162115..0bf8efab 100644 --- a/book/contents/basic/compound-type/string-slice.md +++ b/book/contents/basic/compound-type/string-slice.md @@ -35,7 +35,7 @@ Bingo,果然报错了,编译器提示`greet`函数需要一个`String`类型 ## 切片(slice) -切片并不是Rust独有的概念,在Go语言中就非常流行,它允许你引用集合中一段连续的元素序列,而不是引用整个集合。 +切片并不是Rust独有的概念,在Go语言中就非常流行,它允许你引用集合中部分连续的元素序列,而不是引用整个集合。 对于字符串而言,切片就是对`String`类型中某一部分的引用,它看起来像这样: ```rust @@ -121,7 +121,7 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta 回忆一下借用的规则:当我们已经有了可变借用时,就无法再拥有不可变的借用。因为`clear`需要清空改变`String`,因此它需要一个可变借用,而之后的`println!`又使用了不可变借用,因此编译无法通过。 -从上述代码可以看出,Rust不仅让我们的`api`更加容易使用,而且也在编译期就消除了大量错误! +从上述代码可以看出,Rust不仅让我们的`API`更加容易使用,而且也在编译期就消除了大量错误! #### 其它切片 因为切片是对集合的部分引用,因此不仅仅字符串有切片,其它集合类型也有,例如数组: @@ -348,9 +348,9 @@ for b in "中国人".bytes() { ## 字符串深度剖析 -那么问题来了,为啥`String`可变,而字符串字面值却不可以? +那么问题来了,为啥`String`可变,而字符串字面值`str`却不可以? -就字符串字面值来说,我们在编译时就知道其内容,最终文本被直接硬编码进可执行文件中。这使得字符串字面值快速且高效,上述特性主要得益于字符串的不可变性。不幸的是,我们不能为了获得这种性能,而把每一个在编译时大小未知的文本放进内存中(你也做不到!). +就字符串字面值来说,我们在编译时就知道其内容,最终字面值文本被直接硬编码进可执行文件中,这使得字符串字面值快速且高效,这主要得益于字符串的不可变性。不幸的是,我们不能为了获得这种性能,而把每一个在编译时大小未知的文本都放进内存中(你也做不到!),因为有的字符串是在程序运行得过程中动态生成的。 对于 `String` 类型,为了支持一个可变、可增长的文本片段,需要在堆上分配一块在编译时未知大小的内存来存放内容,这些都是在程序运行时完成的: - 首先向操作系统请求内存来存放`String`对象 @@ -358,9 +358,9 @@ for b in "中国人".bytes() { 其中第一个由`String::from`完成,它创建了一个全新的String. -重点来了,到了第二部分,就是百家齐放的环节,在有**垃圾回收GC**的语言中,GC来负责标记并清除这些不再使用的内存对象,这些都是自动完成,无需开发者关心,非常简单好用;在无GC的语言,是开发者手动去释放这些内存对象,就像创建对象一样,需要通过编写代码来完成,因为未能正确释放对象造成的结局简直不可估量. +重点来了,到了第二部分,就是百家齐放的环节,在有**垃圾回收GC**的语言中,GC来负责标记并清除这些不再使用的内存对象,这个过程都是自动完成,无需开发者关心,非常简单好用;但是在无GC的语言,需要开发者手动去释放这些内存对象,就像创建对象需要通过编写代码来完成一样,未能正确释放对象造成的结局简直不可估量. -对于Rust而言,安全和性能是写到骨子里的核心特性,使用GC牺牲了性能,使用手动管理内存牺牲了安全,那该怎么办?为此,Rust的开发者想出了一个无比惊艳的办法:变量在离开作用域后,就自动释放其占用的内存: +对于Rust而言,安全和性能是写到骨子里的核心特性,如果使用GC,那么会牺牲性能;如果使用手动管理内存,那么会牺牲安全,这该怎么办?为此,Rust的开发者想出了一个无比惊艳的办法:变量在离开作用域后,就自动释放其占用的内存: ```rust { From f337dce78faa6a87e1160ff42c78a72c86e18006 Mon Sep 17 00:00:00 2001 From: Jesse <35264598+JesseAtSZ@users.noreply.github.com> Date: Tue, 11 Jan 2022 20:16:42 +0800 Subject: [PATCH 07/10] Update tuple.md --- book/contents/basic/compound-type/tuple.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/book/contents/basic/compound-type/tuple.md b/book/contents/basic/compound-type/tuple.md index be1c29bd..5f0656b1 100644 --- a/book/contents/basic/compound-type/tuple.md +++ b/book/contents/basic/compound-type/tuple.md @@ -2,7 +2,7 @@ 元组是由多种类型组合到一起形成的,因此它是复合类型,元组的长度是固定的。 -通过以下语法可以创建一个元组: +可以通过以下语法创建一个元组: ```rust fn main() { let tup: (i32, f64, u8) = (500, 6.4, 1); @@ -25,11 +25,11 @@ fn main() { } ``` -上述代码首先创建一个元组,然后将其绑定到`tup`上,接着使用`let (x, y, z) = tup;`来完成一次模式匹配,因为元组是`(n1,n2,n3)`形式的,因此我们用一模一样的`(x,y,z)`形式来进行匹配,然后把元组中对应的值绑定到变量`x`,`y`,`z`上,这就是解构:用同样的形式把一个复杂对象中的值匹配出来。 +上述代码首先创建一个元组,然后将其绑定到`tup`上,接着使用`let (x, y, z) = tup;`来完成一次模式匹配,因为元组是`(n1,n2,n3)`形式的,因此我们用一模一样的`(x,y,z)`形式来进行匹配,元组中对应的值会绑定到变量`x`,`y`,`z`上。这就是解构:用同样的形式把一个复杂对象中的值匹配出来。 ### 用`.`来访问元组 -模式匹配可以让我们一次性把元组中的值全部或者部分获取出来,如果想要访问某个特定元素,那模式匹配就略显繁琐,对此,Rust提供了`.`的访问方式: +模式匹配可以让我们一次性把元组中的值全部或者部分获取出来,如果只想要访问某个特定元素,那模式匹配就略显繁琐,对此,Rust提供了`.`的访问方式: ```rust fn main() { let x: (i32, f64, u8) = (500, 6.4, 1); @@ -64,6 +64,6 @@ fn calculate_length(s: String) -> (String, usize) { `calculate_length`函数接收`s1`字符串的所有权,然后计算字符串的长度,接着把字符串所有权和字符串长度再返回给`s2`和`len`变量。 -对于其他语言,元组可以用来声明一个3D点,例如`Point(10,20,30)`,虽然使用Rust元组也可以做到:`(10,20,30)`,但是这样写有个非常重大的缺陷: +在其他语言中,可以用结构体来声明一个三维空间中的点,例如`Point(10,20,30)`,虽然使用Rust元组也可以做到:`(10,20,30)`,但是这样写有个非常重大的缺陷: -**不具备任何清晰的含义**,在下一章节中,会提到一种`元组结构体`,可以解决这个问题。 \ No newline at end of file +**不具备任何清晰的含义**,在下一章节中,会提到一种与元组类似的结构体,`元组结构体`,可以解决这个问题。 From bbea17ae1055ba420bc90a50e65dd1321b0ec3b7 Mon Sep 17 00:00:00 2001 From: Jesse <35264598+JesseAtSZ@users.noreply.github.com> Date: Tue, 11 Jan 2022 20:20:02 +0800 Subject: [PATCH 08/10] Update tuple.md --- book/contents/basic/compound-type/tuple.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/contents/basic/compound-type/tuple.md b/book/contents/basic/compound-type/tuple.md index 5f0656b1..d52b6d06 100644 --- a/book/contents/basic/compound-type/tuple.md +++ b/book/contents/basic/compound-type/tuple.md @@ -1,6 +1,6 @@ # 元组 -元组是由多种类型组合到一起形成的,因此它是复合类型,元组的长度是固定的。 +元组是由多种类型组合到一起形成的,因此它是复合类型,元组的长度是固定的,元组中元素的顺序也是固定的。 可以通过以下语法创建一个元组: ```rust From ea835d4061fcd1c99fbcdcdec963b764a4201677 Mon Sep 17 00:00:00 2001 From: Jesse <35264598+JesseAtSZ@users.noreply.github.com> Date: Tue, 11 Jan 2022 20:31:09 +0800 Subject: [PATCH 09/10] Update struct.md --- book/contents/basic/compound-type/struct.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/book/contents/basic/compound-type/struct.md b/book/contents/basic/compound-type/struct.md index ef4915c5..b27dff3f 100644 --- a/book/contents/basic/compound-type/struct.md +++ b/book/contents/basic/compound-type/struct.md @@ -11,7 +11,7 @@ 一个结构体有几部分组成: - 通过关键字`struct`定义 - 一个清晰明确的结构体`名称` -- 数个具名的结构体`字段` +- 几个有名字的结构体`字段` 例如以下结构体定义了某网站的用户: ```rust @@ -22,7 +22,7 @@ struct User { sign_in_count: u64, } ``` -该结构体名称是`User`,拥有4个具名的字段,且每个字段都有对应的类型声明,例如`username`代表了用户名,是一个可变的`String`类型。 +该结构体名称是`User`,拥有4个字段,且每个字段都有对应的字段名及类型声明,例如`username`代表了用户名,是一个可变的`String`类型。 #### 创建结构体实例 为了使用上述结构体,我们需要创建`User`结构体的**实例**: @@ -50,7 +50,7 @@ struct User { user1.email = String::from("anotheremail@example.com"); ``` -需要注意的是,必须要将整个结构体都声明为可变的,才能修改它,Rust不允许单独将某个字段标记为可变: `let mut user1 = User {...}`. +需要注意的是,必须要将整个结构体都声明为可变的,才能修改其中的某个字段,Rust不允许单独将某个字段标记为可变: `let mut user1 = User {...}`. #### 简化结构体创建 下面的函数类似一个构建函数,返回了`User`结构体的实例: @@ -98,7 +98,7 @@ fn build_user(email: String, username: String) -> User { ``` 因为`user2`仅仅在`email`上与`user1`不同,因此我们只需要对`email`进行赋值,剩下的通过结构体更新语法`..user1`即可完成。 -`..`语法说明我们没有显示声明的字段全部从`user1`中自动获取。需要注意的是`..user1`必须在结构体的尾部使用。 +`..`语法表明凡是我们没有显示声明的字段,全部从`user1`中自动获取。需要注意的是`..user1`必须在结构体的尾部使用。 > 结构体更新语法跟赋值语句`=`非常相像,因此在上面代码中,`user1`的部分字段所有权被转移到`user2`中:`username`字段发生了所有权转移,作为结果,`user1`无法再被使用。 > @@ -165,7 +165,7 @@ println!("{:?}", user1); 从图中可以清晰的看出`File`结构体两个字段`name`和`data`分别拥有底层两个`[u8]`数组的所有权(`String`类型的底层也是`[u8]`数组),通过`ptr`指针指向底层数组的内存地址,这里你可以把`ptr`指针理解为Rust中的引用类型。 -该图片也侧面印证了:把结构体中具有所有权的字段转移出去后,将无法再访问该字段,但是可以正常访问其它的字段. +该图片也侧面印证了:**把结构体中具有所有权的字段转移出去后,将无法再访问该字段,但是可以正常访问其它的字段**. ## 元组结构体(Tuple Struct) @@ -198,7 +198,7 @@ impl SomeTrait for AlwaysEqual { ## 结构体数据的所有权 -在之前的`User` 结构体的定义中,我们使用了自身拥有所有权的 `String` 类型而不是基于引用的`&str` 字符串切片类型。这是一个有意而为之的选择,因为我们想要这个结构体拥有它所有的数据,而不是从其它地方借用数据。 +在之前的`User` 结构体的定义中,有一处细节:我们使用了自身拥有所有权的 `String` 类型而不是基于引用的`&str` 字符串切片类型。这是一个有意而为之的选择,因为我们想要这个结构体拥有它所有的数据,而不是从其它地方借用数据。 你也可以让`User`结构体从其它对象借用数据,不过这么做,就需要引入**生命周期**这个新概念(也是一个复杂的概念),简而言之,生命周期能确保结构体的作用范围要比它所借用的数据的作用范围要小。 From f4b5604ad55794ad09e531aa38ad741a1a427f28 Mon Sep 17 00:00:00 2001 From: Jesse <35264598+JesseAtSZ@users.noreply.github.com> Date: Tue, 11 Jan 2022 20:32:15 +0800 Subject: [PATCH 10/10] Update struct.md --- book/contents/basic/compound-type/struct.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/contents/basic/compound-type/struct.md b/book/contents/basic/compound-type/struct.md index b27dff3f..aadabc0b 100644 --- a/book/contents/basic/compound-type/struct.md +++ b/book/contents/basic/compound-type/struct.md @@ -50,7 +50,7 @@ struct User { user1.email = String::from("anotheremail@example.com"); ``` -需要注意的是,必须要将整个结构体都声明为可变的,才能修改其中的某个字段,Rust不允许单独将某个字段标记为可变: `let mut user1 = User {...}`. +需要注意的是,必须要将整个结构体都声明为可变的,才能修改其中的字段,Rust不允许单独将某个字段标记为可变: `let mut user1 = User {...}`. #### 简化结构体创建 下面的函数类似一个构建函数,返回了`User`结构体的实例: