|
|
|
@ -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`,来看看怎么样更好的解决这类问题。 开始之前,先来看看何为`元组`.
|
|
|
|
|
接下来,我们将引入一个高级数据结构 - 结构体`struct`,来看看结构体是怎样更好的解决这类问题。 开始之前,先来看看什么是`元组`.
|
|
|
|
|