讨论元组和结构体,比较、对比
如何定义和实例化结构体
如何定义关联函数
一、结构体
使用struct 关键字声明
Struct User {
name: String, // name 称之为字段
}
实例可变可以使用点号修改结构体某个字段。
Rust不允许只将一个不可变的结构体中某个字段标记为可变。
元组结构体:
1. 给元组命名
2. 使元组成为与其他元组不同的类型
3. 除上述两种情况外使用元组结构体就显得多余和形式化。
类单元结构体
1. 没有任何字段的结构体
2. 该结构体常常在想要在某个类型上实现trait,但不需要在类型中存储数据时发挥作用。
结构体数据的所有权
- 结构体拥有数据所有权控制
- 若结构体中数据存储被其他对象拥有的数据的引用,需要用上生命周期(lifetimes)来确保结构体中引用数据有效性跟结构体本身保持一致。否则编译器会抱怨需要生命周期标识符。
二、结构体示例
两种debug打印结构体方式
前置标识(必须):
#[derive(Debug)]
- println!("rect: {:#?}", rect);
- dbg!(xxx) :
- 直接输出表达式结果值
- 宏调用dbg!的文件和行号
三、方法语法
方法与函数类似:
1. 使用fn关键字和名称声明
2. 拥有参数和返回值
3. 包含在某处调用该方法时会执行的代码
不同点:
1. 方法在结构体的上下文中被定义
2. 并且方法的第一个参数总是self
3. self代表调用该方法的结构体实例
impl Rectangle {
fn area(&self) -> u32 { // &self 实际上是 self: &Self 的缩写
self.width * self.height
}
}
在一个 impl 块中,Self 类型是 impl 块的类型的别名。
我们将某个类型实例能做的所有事情都一起放入 impl 块中,而不是让将来的用户在我们的库中到处寻找 xxxxx 的功能。
方法的名称可以与结构中的字段相同。
Getters:
1. 与字段同名的方法将被定义为只返回字段中的值,而不做其他事情。这样的方法被称为 getters。Rust 并不像其他一些语言那样为结构字段自动实现它们。
2. Getters 很有用,因为你可以把字段变成私有的,但方法是公共的,这样就可以把对字段的只读访问作为该类型公共 API 的一部分。
Rust自动引用和解引用:
1. 方法调用是 Rust 中少数几个拥有这种行为的地方。
2. 当使用 object.something() 调用方法时,Rust 会自动为object添加 &、&mut 或 * 以便使 object 与方法签名匹配。
关联函数
1. 所有在impl块中定义的函数称为关联函数
2. 不以self为第一参数,因此关联函数不是方法
3. 关联函数经常用作返回一个结构体新实例的构造函数
4. 使用结构体名 + :: 语法来调用关联函数:比如let sq = Rectangle::square(3);