19_rust的泛型
提取函数消除重复代码
fn get_largest(list: &[i32]) -> i32 {
let mut max_num = list[0];
for &i in list {
if i > max_num {
max_num = i;
}
}
max_num
}
fn main() {
let n1 = vec![12, 24, 56, 11];
let max_num = get_largest(&n1);
}
泛型
泛型:提高代码复用能力。用于处理重复代码。
泛型是具体类型或其它属性的抽象代替:
- 代码非最终代码,是一种模板,含“占位符”
<T>
- 编译器编译时将占位符替换为具体类型
如 fn get_max<T>(list: &[T]) -> <T> {}
类型参数:常用一个字母,使用CamelCase,T:type的缩写。
使用泛型
函数定义中的泛型
泛型函数:参数类型、返回类型。
fn get_max<T>(list: &[T]) -> <T> {}
Struct中使用泛型
struct st1<T> {
x: T,
y: T,
}
struct st2<T, U> {
x: T,
y: U,
}
fn main() {
let a1 = st1 {x: 5, y: 6};
let a2 = st1 {x: 5, y: 6.0};// 报错expected integer, found floating-point number
let a3 = st2 {x: 5, y: 6.0};
}
Enum定义中使用泛型
可让枚举的变体持有泛型数据类型,如之前用过的:
enum Option<T> {
Some(T),
None,
}
Result<T, E> {
Ok(T),
Err(E),
}
方法的定义中使用泛型
可为struct或enum实现方法的代码中,可使用泛型。
struct st1<T> {
x: T,
y: T,
}
impl<T> st1<T> { // 这是针对泛型T来实现的方法
fn func1(&self) -> &T {
&self.x
}
}
impl st1<i32> { // 这个实现仅对i32类型才有其他类型的st1没有
fn func_i32(&self) -> &i32 {
&self.x
}
}
注:把T放在impl关键字后,表示类型T上实现方法。只针对具体类型实现方法(其余类型没有)
另外struct里的泛型类型参数可和方法的泛型类型参数不同
struct St2<T, U> {
x: T,
y: U,
}
impl<T, U> St2<T, U> {
fn mix<V, W>(self, o: St2<V, W>) -> St2<T, W> {
St2 { // 返回值类型来自两个对象的各一个字段
x: self.x,
y: o.y,
}
}
}
fn main() {
let a1 = St2 {x: 5, y: 6.0};
let a2 = St2 {x: 'c', y: "str"};
let a3 = a1.mix(a2);
println!("x:{} y:{}", a3.x, a3.y);
}
// 输出结果 x:5 y:str
泛型代码的性能
使用泛型的代码和使用具体类型的代码运行速度一样。
因为编译时进行单态化(monomorphization):在编译是将泛型替换为具体类型的过程。
fn main() {
let i = Some(5);
let f = Some(5.0);
}
// 编译时进行展开,相当于如下代码
enum Option_i32 {
Some(i32),
None,
}
enum Option_f64 {
Some(f64),
None,
}
fn main() {
let i = Option_i32::Some(5);
let f = Option_f64::Some(5.0);
}