元组结构体

除了定义常规的结构体之外,也可以定义与元组类似的结构体,称为元组结构体tuple structs),元组结构体的主要特征是没有字段名,只有字段类型,当我们想给整个元组取一个名字,并使元组成为与其他元组不同的类型时,元组结构体是很有用的,这时像常规结构体那样为每个字段命名就显得多余和形式化了,比如定义颜色的RGB和坐标。要定义元组结构体,以struct关键字和结构体名开头并后跟元组中的类型。例如,下面是两个分别叫做ColorPoint元组结构体的定义和用法:

struct Color(i32, i32, i32);struct Point(i32, i32, i32);let black = Color(0, 0, 0);let origin = Point(0, 0, 0);

需要注意blackorigin值的类型不同,因为它们是不同的元组结构体的实例。你定义的每一个结构体有其自己的类型,即使结构体中的字段有着相同的类型。例如,一个获取Color类型参数的函数不能接受Point作为参数,即便这两个类型都由三个i32值组成。在其他方面,元组结构体实例类似于元组:可以将其解构为单独的部分,也可以使用.后跟索引来访问单独的值,等等。

单元结构体

我们也可以定义一个没有任何字段的结构体!它们被称为类单元结构体unit-like structs)因为它们类似于(),即 unit 类型。类单元结构体常常在你想要在某个类型上实现 trait 但不需要在类型中存储数据的时候发挥作用。trait我们会在后面的文章进行介绍。

结构体数据的所有权

struct UserInfo {name: String,age: i32,sex: bool,// true表示男false表示女}

在上面代码示例中,使用了自身拥有所有权的String类型而不是&str字符串 slice 类型。原因就是想要这个结构体拥有它所有的数据,为此只要整个结构体是有效的话其数据也是有效的。这里会提到一个生命周期lifetimes)的概念,后续文章也会介绍哦,生命周期确保结构体引用的数据有效性跟结构体本身保持一致。如果尝试在结构体中存储一个引用而不指定生命周期将会引发程序编译失败:

struct User {username: &str,email: &str,sign_in_count: u64,active: bool,}fn main() {let user1 = User {email: "someone@example.com",username: "someusername123",active: true,sign_in_count: 1,};}

报错信息如下所示:

error[E0106]: missing lifetime specifier -->|2 | username: &str,| ^ expected lifetime parametererror[E0106]: missing lifetime specifier -->|3 | email: &str,|^ expected lifetime parameter

我们会在后续的文章中介绍如何修复这个问题以便在结构体中存储引用。