一、泛型概念
泛型很多编程语言都会实现的特性。在处理数据结构的时候可以带来很大便利性。或者一些工具函数可以处理多种类型。
当然熟悉go的童鞋,可能要说,没有泛型也可以写数据结构啊。这涉及到反射和泛型的一些差别。泛型在性能上更占优势,
因为大部分语言在实现泛型都会选择特例化类型
1.rust泛型特例化
先给v_str初始化一些&str, 然后push一个int。看编译器报错
1
2
3
4
|
fn main() {
let mut v_str = vec!["1123", "345"];
v_str.push(1);
}
|
输出
1
2
3
4
5
6
7
8
|
error[E0308]: mismatched types
--> src/main.rs:3:16
|
3 | v_str.push(1);
| ^ expected `&str`, found integer
error: aborting due to previous error
|
这里的v_str已经是&str类型,再push int就会报错。
所以特例化之后的泛型类型就是具体类型了。泛型不会带来抽象开销,所以效率还是很高的。
2.写法
函数名之后带<T>
, 类型使用<T>
里面的值。
二、实战-实现泛型max函数
1.先按感觉写
1
2
3
4
5
6
7
8
9
10
|
fn max<T>(a: T, b: T) -> T {
if a < b {
return b;
}
return a;
}
fn main() {
println!("Hello, world!");
}
|
2.cargo build
看下输出
从报错上来看,编译器老师傅告诉我们出错原因,和建议。我们先按建议修改下。泛型类型要加下约束,实现了约束的类型可以使用这个max函数。
这个可以理解,编译器加强前置检查。能编译通过后面基本没啥问题。总比某个语言template报错,地球人都看不懂。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
error[E0369]: binary operation `<` cannot be applied to type `T`
--> src/main.rs:2:10
|
2 | if a < b {
| - ^ - T
| |
| T
|
help: consider restricting type parameter `T`
|
1 | fn max<T: std::cmp::PartialOrd>(a: T, b: T) -> T {
| ^^^^^^^^^^^^^^^^^^^^^^
|
3.修改之后的代码
运行成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
fn max<T: std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
return b;
}
return a;
}
fn main() {
println!("{}", max(1, 2));
println!("{}", max(2.2, 1.1));
println!("{}", max("hello", "h"));
}
// output:
// 2
// 2.2
// hello
|
三、实战-实现泛型index函数
在golang有时候要使用index函数,如果是strings or bytes类型还好,标准库里面有,如果是int 就尴尬了。
也可以用reflect实现,就是速度慢点。当然有泛型的rust这点还是不错的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
fn index<T: std::cmp::PartialEq>(a: &[T], b: T) -> i32 {
for (i, item) in a.iter().enumerate() {
if item == &b {
return i as i32;
}
}
return -1;
}
fn main() {
println!("find index:{}", index(&vec![1, 2, 3, 4, 5,], 5));
println!("find index:{}", index(&vec![1, 2, 3, 4, 5,], 6));
println!("find index:{}", index(&vec!["hello", "world"], "world"));
println!("find index:{}", index(&vec!["hello", "world"], "wo qu"));
}
// output
// find index:4
// find index:-1
// find index:1
// find index:-1
|