定义结构体并实例化
类似面向对象编程的类语法
rust
struct Student {
stu_no: i32,
name: String,
register_at: String
}
fn main() {
let tom = Student {
stu_no: 1001,
name: String::from("tom"),
register_at: String::from("2020-01-11"),
};
println!("stu_no: {}", tom.stu_no);
println!("name: {}", tom.name);
println!("register: {}", tom.register_at);
}
字段初始化的简写语法
类似js对象的简写语法,key和value变量同名可以省略
rust
struct Student {
stu_no: i32,
name: String,
register_at: String
}
fn build_student(id:i32, name:String, register_at:String) -> Student {
Student {
stu_no: id, // 不同名是不能缩写语法的
name,
register_at,
}
}
fn main() {
let name = String::from("jerry");
let reg_at = String::from("2022-11-21");
let jerry = build_student(1002, name, reg_at);
println!("stu_no: {}", jerry.stu_no);
println!("name: {}", jerry.name);
println!("register: {}", jerry.register_at);
}
使用结构体更新语法从其他实例创建实例
这个功能类似js的延展符的功能 {...obj1, ...obj2}
rust
struct User {
id: i32,
name: String,
password: String,
is_actived: bool,
is_banned: bool,
is_real_auth: bool,
}
fn main() {
let tom = User {
id: 1001,
name: String::from("tom"),
password: String::from("123456"),
is_actived: true,
is_banned: false,
is_real_auth: true,
};
let jerry = User {
id: 1002,
name: String::from("jerry"),
..tom // 不会覆盖已有的字段
};
println!("jerry.id :{}", jerry.id);
println!("jerry.name :{}", jerry.name);
println!("jerry.password :{}", jerry.password);
println!("jerry.is_actived:{}", jerry.is_actived);
println!("jerry.is_banned :{}", jerry.is_banned);
println!("jerry.is_banned :{}", jerry.is_real_auth);
}
定义类元组结构体
rust
// 类似元组一样的结构体
struct IpAddrV4(u8, u8, u8, u8);
impl IpAddrV4 {
fn to_addr_string(&self) -> String {
let mut addr_str = String::new();
addr_str += self.0.to_string().as_str();
addr_str += ".";
addr_str += self.1.to_string().as_str();
addr_str += ".";
addr_str += self.2.to_string().as_str();
addr_str += ".";
addr_str += self.3.to_string().as_str();
addr_str
}
}
fn main() {
let ip = IpAddrV4(192, 168, 11, 255);
println!("ip: {}", ip.to_addr_string());
}
使用#[derive(Debug)]
- 不用管 trait 和 #[derive(debug)] 是什么, 后续都会学
- 只需要知道, 在结构体上加上这个就可以使用
println!
这个宏来输出, 以便查看信息
rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect = Rectangle {
width: 10,
height: 10
};
println!("rect width : {}", rect.width);
println!("rect height: {}", rect.height);
// 如果没有加上 #[derive] 无法直接输出
println!("rect: {:?}", rect);
// 也可以使用dbg宏
dbg!(rect);
}
实例方法
类似面向对象编程的定义方法
rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn get_area(&self) -> u32 {
self.width * self.height
}
// 多个参数 &Self 就是 &Rectangle 的意思,
// 只不过 Self 是关键字代表当前的 struct
fn can_hold(&self, other_rect: &Self) -> bool {
self.width >= other_rect.width && self.height >= other_rect.height
}
}
fn main() {
let rect = Rectangle {
width: 10,
height: 10
};
let rect2 = Rectangle {
width: 20,
height: 20,
};
println!("rect area: {}", rect.get_area()); // 100
println!("rect2 area: {}", rect2.get_area()); // 100
println!("rect2 can hold rect? {}", rect2.can_hold(&rect));
}
关联函数
关联函数只是返回值是 Rectangle, 但第一个参数并不是 &self
所以不能称之为方法
比如之前一直使用的 String::from 就是一个关联函数, 他的第一个参数并不是 &self
rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
// 有些类似面向对象编程的静态方法
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}
fn main() {
let square = Rectangle::square(10);
dbg!(square);
}
多个 impl
一个结构体可以有多个 impl 块
rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
// 放实例方法
impl Rectangle {
fn get_area(&self) -> u32 {
self.width * self.height
}
fn can_hold(&self, other_rect: &Self) -> bool {
self.width >= other_rect.width && self.height >= other_rect.height
}
}
// 放关联函数
impl Rectangle {
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}
fn main() {
let square = Rectangle::square(10);
dbg!(square);
}
self 和 Self
可以这样理解 self
代表当前实例, 作用类似 Java 的 this
关键字
而 Self
代表当前 impl
的 struct
, 如: impl X
Self
就代表 X