泛型
学习目标
理解泛型的作用
掌握结构体、枚举、函数的泛型
理解单态化
掌握泛型与 trait 的结合
核心概念
为什么需要泛型
fn max_i32 (a: i32 , b: i32 ) -> i32 { if a > b { a } else { b } }
fn max_f64 (a: f64 , b: f64 ) -> f64 { if a > b { a } else { b } }
fn max <T: PartialOrd >(a: T, b: T) -> T {
if a > b { a } else { b }
}
复制
函数泛型
fn largest <T: PartialOrd >(list: &[T]) -> &T {
let mut largest = &list[0 ];
for item in &list[1 ..] {
if item > largest {
largest = item;
}
}
largest
}
fn main () {
let numbers = vec! [34 , 50 , 25 , 100 , 65 ];
println! ("最大数: {}" , largest (&numbers));
let chars = vec! ['y' , 'm' , 'a' , 'q' ];
println! ("最大字符: {}" , largest (&chars));
}
复制
结构体泛型
struct Point <T> {
x: T,
y: T,
}
struct Point2 <T, U> {
x: T,
y: U,
}
impl <T> Point<T> {
fn x (&self ) -> &T {
&self .x
}
}
impl Point <f64 > {
fn distance_from_origin (&self ) -> f64 {
(self .x.powi (2 ) + self .y.powi (2 )).sqrt ()
}
}
fn main () {
let integer_point = Point { x: 5 , y: 10 };
let float_point = Point { x: 1.0 , y: 4.0 };
println! ("距离: {}" , float_point.distance_from_origin ());
}
复制
枚举泛型
enum Option <T> {
Some (T),
None ,
}
enum Result <T, E> {
Ok (T),
Err (E),
}
enum Either <L, R> {
Left (L),
Right (R),
}
impl <L, R> Either<L, R> {
fn is_left (&self ) -> bool {
matches!(self , Either::Left (_))
}
fn unwrap_left (self ) -> L {
match self {
Either::Left (l) => l,
Either::Right (_) => panic! ("called unwrap_left on Right" ),
}
}
}
复制
单态化
fn add <T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
a + b
}
fn main () {
let x = add (1 , 2 );
let y = add (1.0 , 2.0 );
}
复制
实践练习
练习 1:泛型栈
struct Stack <T> {
elements: Vec <T>,
}
impl <T> Stack<T> {
fn new () -> Self {
Stack { elements: Vec ::new () }
}
fn push (&mut self , item: T) {
self .elements.push (item);
}
fn pop (&mut self ) -> Option <T> {
self .elements.pop ()
}
fn peek (&self ) -> Option <&T> {
self .elements.last ()
}
fn is_empty (&self ) -> bool {
self .elements.is_empty ()
}
}
fn main () {
let mut stack = Stack::new ();
stack.push (1 );
stack.push (2 );
println! ("{:?}" , stack.pop ());
}
复制
练习 2:泛型 Pair
struct Pair <T> {
first: T,
second: T,
}
impl <T> Pair<T> {
fn new (first: T, second: T) -> Self {
Pair { first, second }
}
}
impl <T: PartialOrd > Pair<T> {
fn larger (&self ) -> &T {
if self .first >= self .second {
&self .first
} else {
&self .second
}
}
}
fn main () {
let pair = Pair::new (10 , 20 );
println! ("较大的: {}" , pair.larger ());
}
复制
常见错误
1. 缺少 trait bound
fn max <T>(a: T, b: T) -> T {
if a > b { a } else { b }
}
fn max <T: PartialOrd >(a: T, b: T) -> T {
if a > b { a } else { b }
}
复制
2. 泛型参数过多
struct Data <T1, T2, T3, T4, T5> { }
复制
小结
用法 语法 函数泛型 fn f<T>(x: T)结构体泛型 struct S<T> { }枚举泛型 enum E<T> { }impl 泛型 impl<T> S<T> { }单态化 编译时生成具体类型代码,零运行时开销