【百例RUST - 013】泛型
【百例RUST - 013】泛型第一章 基础概述第01节 如果不用泛型实际案例如果我们没有泛型当为不同的类型定义逻辑相同的函数的时候可能出现下面的情况fnmain(){let_a:i8return_i8(2i8);let_b:i16return_i16(2i16);let_c:i32return_i32(2i32);let_d:i64return_i64(2i64);let_e:u8return_u8(2u8);let_f:u16return_u16(2u16);let_g:u32return_u32(2u32);let_h:u64return_u64(2u64);}// 如果没有泛型的情况下, 当不同的类型定义逻辑相同的函数的情况下, 可能会出现下面的情况:fnreturn_i8(v:i8)-i8{v}fnreturn_i16(v:i16)-i16{v}fnreturn_i32(v:i32)-i32{v}fnreturn_i64(v:i64)-i64{v}fnreturn_u8(v:u8)-u8{v}fnreturn_u16(v:u16)-u16{v}fnreturn_u32(v:u32)-u32{v}fnreturn_u64(v:u64)-u64{v}这样的操作会显得代码写出来很繁琐因为他们逻辑完全相同。第02节 如果使用泛型那么我们可以使用泛型完成上述的功能实现。案例代码fnmain(){let_a:i8return_value(2i8);let_b:i16return_value(2i16);let_c:i32return_value(2i32);let_d:i64return_value(2i64);let_e:u8return_value(2u8);let_f:u16return_value(2u16);let_g:u32return_value(2u32);let_h:u64return_value(2u64);}// 使用泛型的写法fnreturn_valueT(v:T)-T{v}第03节 结论通过上述的案例我们可以得到下面的几点结论1、泛型是具体类型或者其它属性的抽象代替用于减少代码的重复。 2、在编写Rust代码时可以用泛型来表示各种各样的数据类型等到编译阶段泛型则被替换成它所代表的的具体的数据类型。注意事项在 Rust 当中, 使用泛型不会造成持续上的性能损失。 1、因为 Rust 通过在编译时进行泛型代码的单态化来保存效率。就是在编译时, 把泛型换成了具体的类型 2、单态化是通过填充编译时使用的具体类型, 将通过代码转换为特定代码的过程第二章 常用场景第01节 在结构体中定义泛型在结构体当中定义泛型基础案例代码#[derive(Debug)]structPointT{x:T,y:T,}fnmain(){// 当 point的两个字段都是整型letinteger:Pointi32Point{x:1,y:2};println!({:?},integer);// 当 point的两个字段都是浮点型letfloat:Pointf32Point{x:0.99,y:1.99};println!({:?},float);}// Point { x: 1, y: 2 }// Point { x: 0.99, y: 1.99 }在结构体当中定义不同的类型#[derive(Debug)]structPointM,N{x:M,y:N,}fnmain(){leta:Pointi32,f64Point{x:1,y:2.0};println!({:?},a);letb:Pointf64,i32Point{x:1.99,y:3};println!({:?},b);}// Point { x: 1, y: 2.0 }// Point { x: 1.99, y: 3 }第02节 在枚举当中定义泛型系统标准库的案例在系统库Option当中的代码如下enumOptionT{Some(T),None,}同样的案例还有Result的类型其定义如下enumResultT,E{Ok(T),Err(E),}下面我们列举自定义的枚举中编写的泛型案例#[derive(Debug)]enumMessageT,U{Msg1(u32),Msg2(T),Msg3(U),}fnmain(){let_msg1:Messageu32,StringMessage::Msg1(1u32);let_msg2:Messageu8,StringMessage::Msg2(2u8);let_msg3:Messageu8,StringMessage::Msg3(hello.to_string());println!({:?},_msg1);println!({:?},_msg2);println!({:?},_msg3);}// Msg1(1)// Msg2(2)// Msg3(hello)第03节 在方法当中定义泛型案例1#[derive(Debug)]structPointT{x:T,y:T,}implTPointT{fnget_x(self)-T{self.x}fnget_y(self)-T{self.y}}fnmain(){letp:Pointi32Point{x:1,y:2};println!({:?},p);println!(x {},p.get_x());println!(y {},p.get_y());}// Point { x: 1, y: 2 }// x 1// y 2案例2#[derive(Debug)]structPointT,U{x:T,y:U,}implT,UPointT,U{fnminxupV,W(self,other:PointV,W)-PointT,W{Point{x:self.x,y:other.y}}}fnmain(){letp1:Pointi32,f64Point{x:5,y:10.04};letp2:Pointstr,charPoint{x:hello,y:c};letp3:Pointi32,charp1.minxup(p2);// 在这里 p1.minxup(p2) --- 传入到上面的函数中 selfp1 otherp2// 因为 selfp1 那么 x 的取值应该是 p1 的取值, 也就是 p3.x p1.x --- p3.x 5// 因为 otherp2 那么 y 的取值应该是 p2 的取值, 也就是 p3.y p2.y --- p3.y cprintln!(p3.x {}, p3.y {},p3.x,p3.y);}// p3.x 5, p3.y c