结构体和我们前面学习的元组类似,结构体中的每一项都可以是不同的数据类型。和元组不同的地方在于,我们需要给结构体的每一项命名。结构体较元组的优势是:我们声明和访问数据项的时候不必使用索引,可以直接使用名字。

声明结构体

我们直接看一个结构体的例子:

struct User {     username: String,     email: String,     sign_in_count: u64,     active: bool, }

结构体使用关键字 struct 开头,紧跟结构体的名字,之后就是大括号包裹的多条结构体数据项,每个数据项由名字和类型组成,我们把每个数据项称为字段。

结构体实例化

我们声明了一个结构体后,如何使用它呢?接下来创建一个结构体的实例:

let user1 = User {     email: String::from("someone@example.com"),     username: String::from("someusername123"),     active: true,     sign_in_count: 1, };

可以看到,创建结构体实例 (结构体实例化) 是直接以结构体名字开头,之后就是大括号包裹的键值对。这些键值对顺序和声明结构体的顺序无关,换句话说,声明结构体就是定义一个通用的模版,结构体实例化就是给模版填充值。

结构体数据的存取

创建了结构体实例,那我们应该如何存取实例中的数据呢?比如我们要获取邮箱信息,可以 user1.email 获取邮箱内容,如果实例是可变的,我们可以直接给它赋值。直接看个赋值的例子吧:

let mut user1 = User {     email: String::from("someone@example.com"),     username: String::from("someusername123"),     active: true,     sign_in_count: 1, };  user1.email = String::from("anotheremail@example.com");

这个实例整个都是可变的,如果我只想修改 email 和 username 两个字段,而不想修改其它的字体,应该怎么办呢?

修改部分字段

要知道,rust 不允许我们只把部分字段标记为可变。那我们可不可以把这个结构体放在函数中,让函数返回一个新的实例呢?看例子:

fn build_user(email: String, username: String) -> User {     User {         email: email,         username: username,         active: true,         sign_in_count: 1,     } }

在这个例子中,函数参数名字和结构体字段名字是相 的,如果有很多字段,一个一个地写名字和参数是很无聊的,不过,rust 为我们提供了简写的方式

结构体字段初始化简写

我们直接看例子吧:

fn build_user(email: String, username: String) -> User {     User {         email,         username,         active: true,         sign_in_count: 1,     } }

email 和 username 的结构体字段名字和函数传入的参数变量的名字是相同的,我们可以只写一遍。

结构体更新