跳到主要内容

在struct中使用泛型

泛型

定义不局限名称,可以写任意的一个字母,最好是大写,因为从编程以来,认识的使用泛型的基本都是使用的大写字母,但是肯定会有一对<>进行包裹。

背景:

现在有一个积分平台,老同学使用的是i32类型作为积分的类型;现在有一个需求要支持f32类型的,这就需要泛型来支持。

user_model.rs
pub struct UserScore<A, B> {
// 泛型
pub user_id: A,
pub score: B,
pub comment: &'static str,
}

pub fn new_user_score_a() -> UserScore<i32, i32> {
UserScore {
user_id: 0,
score: 0,
comment: "A类用户",
}
}

这里的AB可以自己定义名称,但是如果使用了,就得保持一致

使用

main.rs
use models::user_model::{new_user_score_a, new_user_score_b};

// mod lib; // lib.rs 或者 lib/mod.rs
mod models;

fn main() {

let mut user_score_a = new_user_score_a();
user_score_a.user_id = 101;
user_score_a.score = 10;
println!("{:?}", user_score_a);

let mut user_score_b = new_user_score_b();
user_score_b.user_id = "#EFff";
user_score_b.score = 10.0;
println!("{:?}", user_score_b);
}

打印结果:

cargo build && cargo run

UserScore { user_id: 101, score: 10, comment: "A类用户" }
UserScore { user_id: "#EFff", score: 10.0, comment: "B类用户" }

"struct类"方法中使用泛型

基于上面的代码,我们新建类方法

impl<A, B> UserScore<A, B> {
pub fn get_user_type(&self) -> &'static str {
// 表达式
&self.comment
}

pub fn get_user_id(&self) -> &A {
&&self.user_id
}
}

这样无论你调用的时候传入的是什么类型,这里都有与之对应的类型结果

main.rs
use models::user_model::{new_user_info, new_user_score_a, new_user_score_b, UserInfo};

// mod lib; // lib.rs 或者 lib/mod.rs
mod models;

fn main() {

let mut user_score = new_user_score_a();
user_score.user_id = 101;
user_score.score = 10;
println!("{:?}", user_score);
println!("{:?}", user_score.get_user_type());
println!("{:?}", user_score.get_user_id());

let mut user_score_b = new_user_score_b();
user_score_b.user_id = "#EFff";
user_score_b.score = 10.0;
println!("{:?}", user_score_b);
println!("{:?}", user_score_b.get_user_type());
println!("{:?}", user_score_b.get_user_id());
}

cargo build && cargo run

UserScore { user_id: 101, score: 10, comment: "A类用户" }
"A类用户"
101
UserScore { user_id: "#EFff", score: 10.0, comment: "B类用户" }
"B类用户"
"#EFff"