前言
struct
或者结构体,是一种定制化的数据类型,用来将关联项打包以形成一个有意义的整体。在OOP中,结构体可以类比为对象的数据属性。这个与C++类似,不过class的概念被抛弃了。
主要内容
- 比较结构体和元组tuple
- 如何定义、实例化结构体
- 如何定义关联函数即方法,即指定结构体的行为
结构体和枚举是创建新类型的基石并利用编译器的类型检查系统。
定义、实例化结构体
结构体和元组类似,都包括多个关联数据,数据的类型可以不同。
不同于元组,结构体的值都需要命名,这就提供了更高的灵活性,不必依赖于位置。
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
fn main() {
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");
}
先定义,后使用,与go的struct使用类似,比C++冗余,但是更清晰?
所有成员默认公开,mut只能修饰整个结构体,不能修饰单个成员。
简化初始化
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
fn build_user(email: String, username: String) -> User {
User {
email,
username,
active: true,
sign_in_count: 1,
}
}
果然都觉得冗长,可以不加成员名称。
用其它示例初始化新对象
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
fn main() {
// --snip--
let user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
let user2 = User {
email: String::from("another@example.com"),
..user1
};
}
除了email成员,user2其它都与user1相同。比之C++更灵活?C++要支持这种,那就要新定义一个构造函数了。
…user1必须最后一个,指明剩下的成员都由use1指定了。称之为结构体更新。
注意,这里是赋值操作,可能存在数据move移动。在例子中,user1赋值给user2之后,将不能被使用。因为username是String类型,没有实现Copy trait,它被转移给user2了。
使用没有命名字段的元组结构体来创建不同类型
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}
给予类型相同,意义不同的元组不同类型,提供可读性、复用性?
当然,因为Point Color是不同类型,所以origin和black不能相互赋值的,虽然它们的底层实际相同。rust有没有类似C/C++的强制类型转换?
无任何成员的类单元(unit)结构体
类似(),即单元类型。可以为没有任何成员的类型实现trait。
struct AlwaysEqual;
fn main() {
let subject = AlwaysEqual;
}
结构体数据的所有权
struct User {
active: bool,
username: &str,
email: &str,
sign_in_count: u64,
}
fn main() {
let user1 = User {
email: "someone@example.com",
username: "someusername123",
active: true,
sign_in_count: 1,
};
}
username和email定义为引用而不是值,此时没有声明两者的生命期,编译出错。
| ^ expected named lifetime parameter