赞
踩
泛型是指把类型抽象成一种“参数”, 数据和算法都针对这种抽象的类型参数来实现, 而不针对具体类型。 当我们需要真正使用的时候, 再具体化、 实例化类型参数。 使用泛型可以编写更为抽象的代码, 减少工作量。
Rust中的泛型属于静多态, 它是一种编译期多态。 在编译期,不管是泛型枚举,还是泛型函数和泛型结构体, 都会被单态化。单态化是编译器进行静态分发的一种策略。
使用不同类型参数将泛型类型单体化后, 获得的是完全不同的具体类型。 如Option<i32>和Option<i64>是完全不同的类型, 不可通用, 也不可相互转换。 当编译器生成代码的时候, 它会为每一个不同的泛型参数生成不同的代码。
最常见的泛型应用莫过于容器,Vec<T>、HashMap<K, V>都是泛型类型的应用。比如,Vec<T>在使用中可以指定T的类型为i32或String等——Vec<i32>或者Vec<String>。
- fn main() {
- let mut vec_int: Vec<i32> = vec![10, 20];
- vec_int.push(30);
- }
泛型枚举是指枚举值类型是泛型类型。标准库提供的Option<T>就是一个应用广泛的泛型枚举。Option<T>表示可能有值,也可能无值这一抽象概念,Some(T)表示可能的值可以是任意类型T,None表示不存在。
- enum Option<T> {
- Some(T),
- None,
- }
-
- fn output(age:i32) -> Option<i32>{
- if age > 18{
- return Some(age)
- }else{
- return None
- }
- }
-
- fn main() {
- let ret1 = output(19);
- println!("{:?}",ret1);
- let ret2 = output(13);
- println!("{:?}",ret2);
-
- }
泛型类型的结构体是指结构体的字段类型是泛型类型,它可以拥有一个或多个泛型类型。定义泛型结构体时,可以在结构体名称后面带上<T>或<T, U>等,在定义字段的类型时使用T或U。我们在定义Num<T, U>时仅使用了两个个泛型,T和U可以相同也可以不同。如果是Nu<T>这个定义表明Nu<T>结构体对某个类型T是通用的。字段data与num都同时属于这个类型。假如我们像下边注释掉的代码一样使用不同的值类型来创建Nu<T>实例,那么代码是无法通过编译的。
- #[derive(Debug)]
- struct Num<T,U> {
- data: Option<T>,
- num: U
- }
- #[derive(Debug)]
- struct Nu<T> {
- data: Option<T>,
- num: T
- }
- fn main() {
- let ret = Num{data:Some(1), num:"hello"};
- println!("{:?}",ret);
- //let ret = Nu{data:Some(1), num:"hello"};
- //println!("{:?}",ret);
- }
函数的参数和返回值都可以是泛型类型,带有泛型类型的参数或返回值的函数叫作泛型函数。泛型函数不要求所有参数都是泛型,可以只是某个参数是泛型。在定义泛型函数时可以在函数名称后面带上<T>,在定义参数或返回值的类型时使用T。
编译之后的foo(5)和foo("hello".to_string()),分别生成对应的foo函数,fn foo(x:i32)->i32和fn foo(x: String)->String。
- fn foo<T>(x: T) -> T {
- return x;
- }
-
-
- fn main() {
- println!("{}", foo(5));
- println!("{}", foo("hello".to_string()));
- }
-
- //fn foo(x: i32) -> i32 {
- // return x;
- //}
-
- //fn foo<T>(x: String) -> String {
- // return x;
- //}
impl的时候也可以使用泛型。 在impl<Trait>for<Type>{}这个语法结构中, 泛型类型既可以出现在<Trait>位置, 也可以出现在<Type>位置。与其他地方的泛型一样, impl块中的泛型也是先声明再使用。 在impl块中出现的泛型参数, 需要在impl关键字后面用尖括号声明。
- #[derive(Debug)]
- struct Container<T> {
- item: T
- }
-
- impl<T> Container<T> {
- fn new(item: T) -> Self {
- Container { item }
- }
- }
- fn main() {
- let c = Container::new(9);
- println!("{:?}",c);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。