结构体基础
结构体的基本定义方式和使用方式:
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
// 注意这里必须制定所有的作用域,否则会报错!!
let user1 = User {
username: String::from("foo"),
email: String::from("foo@mail.com"),
sign_in_count: 100,
active: true,
};
}
上述的结构体是不可变的,如果想要在运行的时候改变结构体的值,需要声明为可变的结构体:
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
// 注意这里必须制定所有的作用域,否则会报错!!
let mut user2 = User {
username: String::from("foo"),
email: String::from("foo@mail.com"),
sign_in_count: 100,
active: true,
};
user2.username = String::from("foo1");
}
如果我们想用默认值的方式制定结构,可以利用函数expression
的方式执行,代码如下:
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn build_user(name_: String, email_: String) -> User {
User {
username: name_,
email: email_,
sign_in_count: 0,
active: false,
}
}
fn main() {
// 不可变的结构
let name1 = String::from("foo1");
let email1 = String::from("foo1@Eemail.com");
let user1 = build_user(name1, email1);
println!("user1: {}, {}, {}, {}", user1.username, user1.email, user1.sign_in_count, user1.active);
// 可变的结构
let name2 = String::from("foo2");
let email2 = String::from("foo2@Eemail.com");
let mut user2 = build_user(name2, email2);
user2.email = String::from("foo22.email.com");
println!("user1: {}, {}, {}, {}", user2.username, user2.email, user2.sign_in_count, user2.active);
}
如果上述函数中,传入的参数和结构提内部结构的名字一样,则可以省略对应的名称,代码实例:
struct User {
name: String,
email: String,
age: u8,
}
fn build_user(name: String, email: String) -> User {
User {
name, // 同名直接省略
email, // 同名直接省略
age: 0,
}
}
fn main() {
let name = String::from("foo");
let email = String::from("foo@mail.com");
let user1 = build_user(name, email);
println!("user: {} {} {}", user1.name, user1.email, user1.age);
}
如果一个结构体实例想要使用之前实例的一些值,可以使用下面的方式:
fn build_user(name: String, email: String) -> User {
User {
name,
email,
age: 0,
}
}
fn main() {
let name = String::from("foo");
let email = String::from("foo@mail.com");
let user1 = build_user(name, email);
println!("user1: {} {} {}", user1.name, user1.email, user1.age);
let user2 = User {
name: String::from("foo2"),
..user1 // 注意没有其他符号
};
println!("user2: {} {} {}", user2.name, user2.email, user2.age);
}
结构体的作用域可以是无名的,类似于tuple
;不过,和tuple
不同,使用=
的时候,ownership会转移的,代码实例:
struct Color(i32, i32, i32);
fn main() {
let black = Color(0, 0, 0);
let black1 = black; // black已经是空的了
println!("RGB: {} {} {}", black1.0, black1.1, black1.2);
}
结构体的方法
直接给出代码实例:
struct Rect {
width: u32,
height: u32,
}
impl Rect { // 声明这是实现Rect结构的方法
fn area(&self) -> u32 { // self类比python的即可
self.width * self.height
}
fn can_hole(&self, other: Rect) -> bool { // other是正常的参数
self.width > other.width && self.height > other.height
}
}
fn main() {
let rect1 = Rect{width: 10, height: 20};
let rect2 = Rect{width:20, height: 15};
println!("rect1 area = {}", rect1.area());
println!("rect2 can hod rect1 ? {}", rect2.can_hole(rect1));
}
上述的impl
可以有多个块。rust中,方法统一使用.
方式。这区别于在C++中使用->
的方式。