当代码中重复的部分多时,我们可以将重复的代码放入一个函数中,通过调用函数,来减少代码的臃肿。
当多种类型都要实现一个功能,我们可以将该类型抽象出来。
在编写代码时将类型进行隐藏,使编写的代码更加通用。
fn get_data<T>(list : &[T]) -> &T {
&list[1]
}
用T来表示类型;
声明一个泛型函数,要在函数名后加<>, 里边是泛型的类型;
这个函数签名
表示接受一个T类型的数组切片,返回一个T元素引用
let list1 = [11,12,13,14];
let list2 = ['a','b','c','D'];
let l1 = get_data(&list1);
let l2 = get_data(&list2);
//因为函数需要的传参是泛型,没有指定类型,所以可以传入不同的类型
struct Point<T> {
x : T,
y : T,
}
struct Buff<T,U> {
x : T,
y : U,
}
结构体Point 有两个类型相同的参数 x,y;
结构体Buff 有两个类型不同的参数 x,y;
let d1 = Point{x : 2, y : 3};
let d2 = Point{x : 1.0, y : 2.0};
//可以定义多个泛型
let d3 = Buff{x: 1,y : 12.3};
let d4 = Buff{x : 21.3,y : 'a'};
impl<T> Point<T> { //impl后的,表示针对泛型T的方法
fn getx(&self) -> &T {
&self.x
}
}
//如果将泛型实例化
impl Point<i32> {
fn geti32(&self) -> i32{ //这个方法就只有i32类型的才能使用
self.x
}
}
impl<T,U> Buff<T,U> {
fn transform<W,X>(self,other : Buff<W,X>) -> Buff<T,X> {
Buff{
x : self.x,
y : other.y,
}
}
}
方法的使用
let x1 = d1.getx();
let x = d1.geti32();
let x = d2.getx();
//方法函数的泛型可以和结构体泛型不一致
let d5 = d3.transform(d4);
//在编译时,所有的泛型都会为编译器解析为具体的单态。
枚举的泛型:Option,Result