泛型与trait
2021-08-28 本文已影响0人
简书网abc
1. 在函数中使用泛型
// 参与比较需要实现std::cmp::PartialOrd 这个特性
fn main() {
fn largest<T: std::cmp::PartialOrd>(list: &[T]) -> &T {
let mut largest: &T = &list[0];
for item in list.iter() {
if item > largest {
largest = item;
}
}
return largest;
}
let number_list = vec![34, 50, 25, 100, 342];
let result = largest(&number_list);
println!("The largest number is {}", result);
let char_list = vec!['y', 'm', 'a', 'q'];
let result = largest(&char_list);
println!("The largest char is {}", result);
}
2. 在结构体中定义泛型
#[derive(Debug)]
// 在结构体中定义泛型
struct Point<T, U> {
x: T,
y: U,
}
fn main() {
let both_integer = Point{x: 4, y: 5};
println!("both_integer : {:?}", both_integer);
}
3. 在结构体方法中定义泛型
struct Point<T, U> {
x: T,
y: U,
}
// impl 块本身的泛型并没有阻碍其内部方法具有泛型的能力:
impl <T, U> Point<T, U> {
fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
Point {
x: self.x,
y: other.y,
}
}
}
fn main() {
let p1 = Point { x: 5, y: 10.4 };
let p2 = Point { x: "Hello", y: 'c'};
let p3 = p1.mixup(p2);
println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}
//结果: p3.x = 5, p3.y = c
4. 默认特性
trait Descriptive {
fn describe(&self) -> String { //在这里定义默认特性
String::from("[object]")
}
}
struct Person {
name: String,
age: u8,
}
//在这里实现这个特性
impl Descriptive for Person {
//覆盖默认实现
fn describe(&self) -> String {
format!("my name is {}, age is {}", self.name, self.age)
}
}
fn main() {
let cali = Person{
name: String::from("Ming"),
age: 123,
};
println!("{}", cali.describe());
}
//结果: my name is Ming, age is 123
5, trait作为参数
// 功能的定义者 接口
pub trait Summary {
fn summarize_author(&self) -> String;
fn summarize(&self) -> String {
format!("(Read from Summary {} ... )", self.summarize_author())
}
}
// 功能的实现者 结构体
struct Person {
name: String,
}
impl Summary for Person {
fn summarize_author(&self) -> String {
format!("(Read from person {} ... )", self.name)
}
}
// 功能的 调用者
fn notify<T: Summary>(item: T) {
println!("{}", item.summarize())
}
fn main() {
let obj = Person{
name: "MingMing".to_string(),
};
// 使用者
notify(obj); //在此处被正式使用
}
//结果: (Read from Summary (Read from person MingMing ... ) ... )
6. 使用 trait bound 有条件地实现方法
// 根据 trait bound 在泛型上有条件的实现方法
use std::fmt::Display;
// 类型 Pair<T> 总是实现了 new 方法,
// 不过只有那些为 T 类型实现了 PartialOrd trait (允许比较) 和 Display trait (启用打印)的 Pair<T>
// 才会实现 cmp_display 方法
struct Pair<T> {
x: T,
y: T,
}
impl<T> Pair<T> {
//结果体关联函数的定义
fn new(x: T, y: T) -> Self { // Self 和 self 啥区别???
Self {
x,
y
}
}
}
impl<T: Display + PartialOrd> Pair<T> {
// 使用 trait bound 有条件地实现方法
fn comp_display(&self) {
if self.x >= self.y {
println!("max num is {}", self.x);
} else {
println!("max num is {}", self.y);
}
}
}
fn main() {
let pp = Pair::new(234, 88);
pp.comp_display();
}
//结果: max num is 234
7. 对任何实现了特定trait的类型有条件的实现trait
//对任何实现了特定trait的类型有条件的实现trait
// 有点类似于类继承
trait GetName {
fn get_name(&self) -> &String;
}
trait PrintName {
fn print_name(&self);
}
//为实现了 GetName 特性的类型 实现 PrintName 特性(有条件)
impl <T: GetName> PrintName for T {
fn print_name(&self) {
println!("name is {}", self.get_name())
}
}
struct Student {
name: String,
}
// 这里实现了 GetName 就相当于实现了 PrintName
// 这种用法有点类似于类继承
impl GetName for Student {
fn get_name(&self) -> &String {
&self.name
}
}
fn main() {
let s = Student{
name: String::from("xiao_ming"),
};
s.print_name()
}
// 结果: name is xiao_ming
8. 特性作为返回值
trait GetAge {
fn get_age(&self) -> u32;
}
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("xiao_ming"),
age: 15,
}
}
fn main() {
let s = produce_item_with_age();
println!("age is = {:?}", s.get_age());
}
//结果: age is = 15