Rust学习Day5:结构体介绍和使用
结构体的定义与实例化
定义:
需要使用struct关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,我们称为 字段(field)
示例:定义一个存储用户账号信息的结构体
rust
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
实例化
不可变实例
示例:实例化一个不可变的实例
rust
fn main() {
let user1 = User{
actve: true,
username: String::from("aaa123"),
email: String::from("aaa123@qq.com"),
sign_in_coun: 1,
}
}
可变实例
示例1:创建一个可变的实例
rust
fn main(){
let mut user1 = User{
actve: true,
username: String::from("aaa123"),
email: String::from("aaa123@qq.com"),
sign_in_coun: 1,
}
// 不可变的可以修改
user1.email = String::from("aaa234@qq.com");
println!("email: {}", user1.email); // 输出 aaa234@qq.com
}
示例2:定义一个build函数,用来传参和返回实例
rust
fn build_user(email: String, username:String) -> User{
User {
active: true, // 默认值
username: username, // 使用传递进来的参数
email: email, // 同上
sign_in_count: 1, // 默认值
}
}
示例3:使用字段初始化简写语法 (需要参数么和字段名一致)
rust
// 在示例2中,入参是完全一致的也可以按照如下格式,与上面的效果一致
fn build_user(email: String, username:String) -> User{
User {
active: true, // 默认值
username,
email,
sign_in_count: 1, // 默认值
}
}
示例4: 使用定义好的实例来设置一个新的
rust
let user2 = User {
email: String::from("aaa@qq.com"),
..user1 // 其他参数使用user1中的 当使用了结构体更新语法时,旧实例的所有权将被移动到新实例中,因此旧实例将不再有效
}
示例5:使用没有明明字段的元组结构来创建不同的类型
rust
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}
结构体示例程序
结构体的使用
示例1,计算面积的使用
rust
fn main(){
// 常规使用
let width1 = 30;
let height1 = 50;
// 计算
println!("The area of the rectangle is {} square pixels.", area(width1, height1));
// 使用元组的方式
let rect1 = (30, 50);
println!("The area of the rectangle is {} square pixels.", area(rect1.0, rect1.1));
// 使用结构体的方式
let rect2 = Rectangle {
width: 30,
height: 50,
};
println!("The area of the rectangle is {} square pixels.", area_struct(&rect2));
}
// 计算面积函数定义
fn area(width: u32, height: u32) -> u32 {
width * height
}
// 定义结构体
struct Rectangle {
width: u32,
height: u32,
}
示例2:结构体的打印
rust
fn main(){
let rect2 = Rectangle {
width: 30,
height: 50,
};
// 输出方式一 通过xx.key的形式
println!("width: {}", rect2.width); // 输出30
// 输出方式二 结构体添加#[derive(Debug)] 然后{:?}的形式
println!("rect2 is {:?}", rect2); // 使用:?打印
// 输出方式二的另一种方式, 使用dbg!
dbg!(&rect2); // 使用dbg!宏打印,包含文件名和行号
}
#[derive(Debug)] // 方式2:通过派生Debug trait来增加实用功能,可以使用{:?}来打印结构体实例
struct Rectangle {
width: u32,
height: u32,
}
方法语法
定义:
方法(method)与函数类似:它们使用 fn 关键字和名称声明,可以拥有参数和返回值,同时包含在某处调用该方法时会执行的代码。不过方法与函数是不同的,因为它们在结构体的上下文中被定义,并且它们第一个参数总是 self,它代表调用该方法的结构体实例。
定义方法:
示例1:常规使用
rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
rect1.area()
);
}
示例2:定义与变量相同的方法
rust
impl Rectangle {
fn width(&self) -> bool {
self.width > 0
}
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
if rect1.width() {
println!("The rectangle has a nonzero width; it is {}", rect1.width);
}
}
示例3:定义带有更多参数的方法
rust
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
let rect2 = Rectangle {
width: 10,
height: 40,
};
let rect3 = Rectangle {
width: 60,
height: 45,
};
println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));
println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3));
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
关联函数
示例:定义正方体
rust
impl Rectangle {
//
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}
多个impl 导入
示例:1 分开形式
rust
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
impl Rectangle {
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
示例2:与上面功能一致
rust
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
本人正在参考官方文档学习这门语言,如果有描述错误的,欢迎各位RUST大神指出;
