通过对《Rust 程序设计语言》,《通过例子学 Rust 中文版》以及令狐一冲老师对相关知识点的学习总结而成。
rust - trait学习
1 trait 的基本含义
- 1,trait 用于定义与其他类型共享的功能,类似于其他语言中的接口
- (1),可以通过trait以抽象的方式定义共享的行为
- (2),可以使用trait bounds指定泛型是任何拥有特定行为的类型
2 定义trait
pub trait GetInformation {
fn get_name(&self) -> &String;
fn get_age(&self) -> u32;
}
3 实现trait
pub trait GetInformation {
fn get_name(&self) -> &String;
fn get_age(&self) -> u32;
}
pub struct Student {
pub name: String,
pub age: u32,
}
impl GetInformation for Student {
fn get_name(&self) -> &String {
&self.name
}
fn get_age(&self) -> u32 {
self.age
}
}
pub struct Teacher {
pub name: String,
pub age: u32,
pub subject: String,
}
impl GetInformation for Teacher {
fn get_name(&self) -> &String {
&self.name
}
fn get_age(&self) -> u32 {
self.age
}
}
fn main() {
let s = Student {name: "xiaoming".to_string(), age: 15};
let t = Teacher {name: String::from("xiaohuang"), age: 35, subject: String::from("math")};
println!("Student, name = {}, age = {}", s.get_name(), s.get_age());
println!("Teacher, name = {}, age = {}", t.get_name(), t.get_age());
println!("Hello, world!");
}
运行结果:
rlk@rlk:lear_trait$ cargo run
Compiling lear_trait v0.1.0 (/home/rlk/work/learn_rust/lear_trait)
Finished dev [unoptimized + debuginfo] target(s) in 0.70s
Running `target/debug/lear_trait`
Student, name = xiaoming, age = 15
Teacher, name = xiaohuang, age = 35
Hello, world!
rlk@rlk:lear_trait$
4 trait作为参数
pub trait GetInformation {
fn get_name(&self) -> &String;
fn get_age(&self) -> u32;
}
pub struct Student {
pub name: String,
pub age: u32,
}
impl GetInformation for Student {
fn get_name(&self) -> &String {
&self.name
}
fn get_age(&self) -> u32 {
self.age
}
}
pub struct Teacher {
pub name: String,
pub age: u32,
pub subject: String,
}
impl GetInformation for Teacher {
fn get_name(&self) -> &String {
&self.name
}
fn get_age(&self) -> u32 {
self.age
}
}
fn print_information(item: impl GetInformation) {
println!("name = {}", item.get_name());
println!("age = {}", item.get_age());
}
fn main() {
let s = Student {name: "xiaoming".to_string(), age: 15};
let t = Teacher {name: String::from("xiaohuang"), age: 35, subject: String::from("math")};
//println!("Student, name = {}, age = {}", s.get_name(), s.get_age());
//println!("Teacher, name = {}, age = {}", t.get_name(), t.get_age());
print_information(s);
print_information(t);
println!("Hello, world!");
}
运行结果:
rlk@rlk:lear_trait$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/lear_trait`
name = xiaoming
age = 15
name = xiaohuang
age = 35
Hello, world!
rlk@rlk:lear_trait$
5 默认实现
trait SchoolName {
fn get_school_name(&self) -> String {
String::from("HongXingSchool")
}
}
pub struct Student {
pub name: String,
pub age: u32,
}
impl SchoolName for Student {}
pub struct Teacher {
pub name: String,
pub age: u32,
pub subject: String,
}
impl SchoolName for Teacher {
fn get_school_name(&self) -> String {
String::from("GuangMingSchool")
}
}
完整的测试程序
pub trait GetInformation {
fn get_name(&self) -> &String;
fn get_age(&self) -> u32;
}
trait SchoolName {
fn get_school_name(&self) -> String {
String::from("HongXingSchool")
}
}
pub struct Student {
pub name: String,
pub age: u32,
}
impl SchoolName for Student {}
impl GetInformation for Student {
fn get_name(&self) -> &String {
&self.name
}
fn get_age(&self) -> u32 {
self.age
}
}
pub struct Teacher {
pub name: String,
pub age: u32,
pub subject: String,
}
impl SchoolName for Teacher {
fn get_school_name(&self) -> String {
String::from("GuangMingSchool")
}
}
impl GetInformation for Teacher {
fn get_name(&self) -> &String {
&self.name
}
fn get_age(&self) -> u32 {
self.age
}
}
fn print_information(item: impl GetInformation) {
println!("name = {}", item.get_name());
println!("age = {}", item.get_age());
}
fn main() {
let s = Student {name: "xiaoming".to_string(), age: 15};
let t = Teacher {name: String::from("xiaohuang"), age: 35, subject: String::from("math")};
//println!("Student, name = {}, age = {}", s.get_name(), s.get_age());
//println!("Teacher, name = {}, age = {}", t.get_name(), t.get_age());
let s_school_name = s.get_school_name();
println!("Student school name = {}", s_school_name);
let t_school_name = t.get_school_name();
println!("Teacher school name = {}", t_school_name);
print_information(s);
print_information(t);
println!("Hello, world!");
}
运行结果
rlk@rlk:lear_trait$ cargo run
Compiling lear_trait v0.1.0 (/home/rlk/work/learn_rust/lear_trait)
Finished dev [unoptimized + debuginfo] target(s) in 0.32s
Running `target/debug/lear_trait`
Student school name = HongXingSchool
Teacher school name = GuangMingSchool
name = xiaoming
age = 15
name = xiaohuang
age = 35
Hello, world!
rlk@rlk:lear_trait$
6 trait_bound
6.1 trait_bound语法
//trait直接作为参数的写法
fn print_information(item: impl GetInformation) {}
//使用trait bound的写法一
fn print_information<T: GetInformation>(item: T) {}
//使用trait bound的写法一
fn print_information<T>(item: T)
where T: GetInformation
{}
6.2 trait_bound语法
//trait直接作为参数的写法
//fn print_information(item: impl GetInformation) {
//使用trait bound的写法
//fn print_information<T: GetInformation>(item: T) {
trait GetName {
fn get_name(&self) -> &String;
}
trait GetAge {
fn get_age(&self) -> u32;
}
fn print_information<T: GetName + GetAge>(item: T) {
println!("name = {}", item.get_name());
println!("age = {}", item.get_age());
}
/*
fn print_information<T>(item: T)
where T: GetName + GetAge
{
println!("name = {}", item.get_name());
println!("age = {}", item.get_age());
}
*/
fn print_information<T>(item: T)
where T: GetName + GetAge
{
println!("name = {}", item.get_name());
println!("age = {}", item.get_age());
}
pub struct Student {
pub name: String,
pub age: u32,
}
impl GetName for Student {
fn get_name(&self) -> &String {
&self.name
}
}
impl GetAge for Student {
fn get_age(&self) -> u32 {
self.age
}
}
fn main() {
let s = Student {name: "xiaoming".to_string(), age: 15};
print_information(s);
println!("Hello, world!");
}
运行结果:
rlk@rlk:learn_trait2$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/learn_trait2`
name = xiaoming
age = 15
Hello, world!
rlk@rlk:learn_trait2$
7 trait作为返回值
trait GetAge {
fn get_age(&self) -> u32;
}
#[derive(Debug)]
pub struct Student {
pub name: String,
pub age: u32,
}
impl GetAge for Student {
fn get_age(&self) -> u32 {
self.age
}
}
fn produce_item_with_age() -> impl GetAge {
Student {
name: String::from("xiaoming"),
age: 15,
}
}
fn main() {
let s = produce_item_with_age();
println!("student age = {}", s.get_age());
println!("Hello, world!");
}
运行结果:
rlk@rlk:learn_trait$ cargo run
Compiling learn_trait v0.1.0 (/home/rlk/projects/learn_trait)
Finished dev [unoptimized + debuginfo] target(s) in 0.39s
Running `target/debug/learn_trait`
student age = 15
Hello, world!
rlk@rlk:learn_trait$
8 使用trait bound有条件的实现
pub trait GetName {
fn get_name(&self) -> &String;
}
pub trait GetAge {
fn get_age(&self) -> u32;
}
struct PeopleMatchInformation<T, U> {
master: T,
student: U,
}
impl<T: GetName + GetAge, U: GetName + GetAge> PeopleMatchInformation<T, U> {
fn print_all_information(&self) {
println!("master name = {}", self.master.get_name());
println!("master age = {}", self.master.get_age());
println!("student name = {}", self.student.get_name());
println!("student age = {}", self.student.get_age());
}
}
struct Teacher {
name: String,
age: u32,
}
impl GetName for Teacher {
fn get_name(&self) -> &String {
&(self.name)
}
}
impl GetAge for Teacher {
fn get_age(&self) -> u32 {
self.age
}
}
struct Student {
name: String,
age: u32,
}
impl GetName for Student {
fn get_name(&self) -> &String {
&(self.name)
}
}
impl GetAge for Student {
fn get_age(&self) -> u32 {
self.age
}
}
fn main() {
let s = Student {name: String::from("xiaoming"), age: 15};
let t = Teacher {name: String::from("xiaohuang"), age: 35};
let m = PeopleMatchInformation{master: t, student: s};
m.print_all_information();
println!("Hello, world!");
}
运行结果:
rlk@rlk:learn_trait2$ cargo run
Compiling learn_trait2 v0.1.0 (/home/rlk/projects/learn_trait2)
Finished dev [unoptimized + debuginfo] target(s) in 0.19s
Running `target/debug/learn_trait2`
master name = xiaohuang
master age = 35
student name = xiaoming
student age = 15
Hello, world!
rlk@rlk:learn_trait2$