结构体
结构体定义
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
#[derive(Debug)]
// Debug 的输出格式。Debug 是一个 trait,它允许我们以一种对开发者有帮助的方式打印结构体,以便当我们调试代码时能看到它的值。
struct Rectangle {
width: u32,
height: u32,
}
使用
let user = User {
email: String::from("apple@apple.com"),
username: String::from("apple"),
active: true,
sign_in_count: 1,
};
println!(
"name= {}, email = {}, active = {}, sign = {}",
user.username, user.email, user.active, user.sign_in_count
);
可变的
let mut user = User {
email: String::from("apple@apple.com"),
username: String::from("apple"),
active: true,
sign_in_count: 1,
};
user.email = String::from("google@google.com");
println!(
"name= {}, email = {}, active = {}, sign = {}",
user.username, user.email, user.active, user.sign_in_count
);
快捷构建
let user = build_user(String::from("a@a.com"), String::from("fk"));
println!(
"name= {}, email = {}, active = {}, sign = {}",
user.username, user.email, user.active, user.sign_in_count
);
fn build_user(email: String, username: String) -> User {
User {
email,
username,
active: true,
sign_in_count: 1,
}
}
元组结构体 tuple structs
定义元组结构体,以 struct 关键字和结构体名开头并后跟元组中的类型。
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
println!("black = {}, {}, {}", black.0, black.1, black.2);
println!("origin = {}, {}, {}", origin.0, origin.1, origin.2);
struct 程序
let width = 40;
let height = 40;
println!("area = {}", area(width, height));
fn area(width: u32, height: u32) -> u32 {
width * height
}
使用元组让代码更易读
let rect = (40, 40);
println!("area = {}", area1(rect));
fn area1(dimensions: (u32, u32)) -> u32 {
dimensions.0 * dimensions.1
}
使用结构体让代码包含更多含义
let rectangle = Rectangle {
width: 32,
height: 32,
};
println!("area {}", area2(&rectangle));
//函数 area 现在被定义为接收一个名叫 rectangle 的参数,其类型是一个结构体 Rectangle 实例的不可变借用。第四章讲到过,我们希望借用结构体而不是获取它的所有权,这样 main 函数就可以保持 rectangle 的所有权并继续使用它,所以这就是为什么在函数签名和调用的地方会有 &
fn area2(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
通过派生 trait 增加实用功能
#[derive(Debug)]
// Debug 的输出格式。Debug 是一个 trait,它允许我们以一种对开发者有帮助的方式打印结构体,以便当我们调试代码时能看到它的值。
struct Rectangle {
width: u32,
height: u32,
}
println!("rectangle = {:?}", rectangle);
println!("rectangle = {:#?}", rectangle);
定义方法
println!("rectangle = {}", rectangle.area());
// 方法的第一个参数总是 self,它代表调用该方法的结构体实例。
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
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));
// 方法的第一个参数总是 self,它代表调用该方法的结构体实例。
impl Rectangle {
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
关联函数
允许在 impl 块中定义 不 以 self 作为参数的函数
let sq = Rectangle::square(3);
println!("sq = {:#?}", sq);
impl Rectangle {
fn square(size: u32) -> Rectangle {
Rectangle {
width: size,
height: size,
}
}
}