Rust 专题
您的位置:rust > Rust专题 > Rust泛型
Rust泛型
作者:--    发布时间:2019-11-20

当要创建多种形式的功能时,即,函数的参数可以接受多种类型的数据。 这可以通过泛型来实现。 泛型也称为“参数多态”,其中多态是多重的,而变形是形式。

有两种方法可以提供通用代码:

  • option<t>
  • result<t, e>

1.option<t>:rust标准库提供option,其中't'是通用数据类型。 它提供了一种类型的泛型。

enum option<t>  
{  
    some(t),  
    none,  
}

在上面的例子中,enum是自定义类型,其中<t>是通用数据类型。 可以用任何数据类型替换t。下面来看看这几个示例 :

let x : option<i32> = some(10);  // 't' is of type i32.  
let x : option<bool> = some(true);  // 't' is of type bool.  
let x : option<f64> = some(10.5); // 't' is of type f64.  
let x : option<char> = some('b'); // 't' is of type char.

在上面的例子中,观察到't'可以是任何类型,即i32boolf64char。 但是,如果左侧的类型与右侧的值不匹配,则会发生错误。 如下示例:

let x : option<i32> = some(10.8);

在上述情况下,左侧的类型是i32,右侧的值是f64类型。 因此,错误发生“类型不匹配”。

  1. result <t,e>: rust标准库提供了另一种数据类型result <t,e>,它是两种类型的泛型,即t&e
enum result<t,e>  
   {  
      ok(t),  
        err(e),  
}

注意:不得不使用't''e',可以使用任何大写字母。

泛型函数

泛型可以在函数中使用,将泛型放在函数的签名中,其中指定参数的数据类型和返回值。

  • 当函数包含类型为t的单个参数时。

语法

fn function_name<t>(x:t)   
// body of the function.

上面的语法包含两部分:

  • <t> : 给定的函数是一种类型的泛型。
  • (x : t) : x 是类型 t

当函数包含多个相同类型的参数时。

fn function_name<t>(x:t, y:t)   
// body of the function.

当函数包含多个类型的参数时。

fn function_name<t,u>(x:t, y:u)  
// body of the function.

完整代码 -

 fn main()  
{  
  let a = vec![1,2,3,4,5];  
  let b = vec![2.3,3.3,4.3,5.3];  
  let result = add(&a);  
  let result1 = add(&b);  
  println!("the value of result is {}",result);  
  println!("the value of result1 is {}",result1);  
}  

fn add<t>(list:&[t])->t  
{  
  let mut c =0;  
  for &item in list.iter()  
  {  
    c= c+item;  
  }  
}

结构定义

结构也可以使用<>运算符在一个或多个字段中使用泛型类型参数。

语法:

struct structure_name<t>   
// body of the structure.

在上面的语法中,在struct_name之后的尖括号中声明泛型类型参数,然后可以在struct定义中使用泛型类型。

下面我们来看一个简单的例子:

struct value<t>  
{  
  a:t,  
  b:t,  
}  
fn main()  
{  
  let integer = value{a:2,b:3};  
  let float = value{a:7.8,b:12.3};  
  println!("integer values : {},{}",integer.a,integer.b);  
  println!("float values :{},{}",float.a,float.b);  
}

执行上面示例代码,得到以下结果 -

integer values : 2,3
float values : 7.8,12.3

在上面的示例中,value <t>结构在一种类型上是通用的,而ab是相同类型的。创建两个实例integerfloatinteger包含i32类型的值,float包含f64类型的值。

下面来看另一个简单的例子。

struct value<t>  
{  
  a:t,  
  b:t,  
}  
fn main()  
{  
  let c = value{a:2,b:3.6};  
  println!("c values : {},{}",c.a,c.b);  
}

执行上面示例代码,得到以下结果:

在上面的示例中,value <t>在一种类型上是通用的,而ab是相同类型的。创建了一个c的实例。c包含不同类型的值,即i32f64。 因此,rust编译器会抛出“不匹配的错误”。

枚举定义

枚举也可以使用通用数据类型。rust标准库提供了option <t>枚举,它包含通用数据类型。 option <t>是一个枚举,其中t是通用数据类型。

  • option<t>

它由两个变体组成,即some(t)none

其中some(t)保存类型t的值,none不包含任何值。

看看下面一段示例代码:

enum option<t>  
{  
    some(t),  
    none,  
}

在上面的例子中,option是一个枚举,它在一个类型t上是通用的。 它由两个变体some(t)none组成。

result<t, e> :可以创建多种类型的泛型,这可以通过result <t,e>来实现。

enum result<t,e>  
{  
    ok(t),  
    err(e),  
}

在上面的例子中,result <t,e>是一个枚举,它在两种类型上是通用的,它由两个变体组成,即ok(t)err(e)

ok(t)保持类型t的值,而err(e)保持类型e的值。

方法定义

可以在结构和枚举上实现这些方法。下来看看一个简单的例子:

struct program<t> {  
    a: t,  
    b: t,  
}  
impl<t> program<t>   
{  
    fn a(&self) -> &t   
{  
       &self.a  
    }  
}

fn main() {  
    let p = program{ a: 5, b: 10 };  

    println!("p.a() is {}", p.a());  
}

输出结果如下 -

p.a() is 5

在上面的例子中,在program <t>上实现了a方法,该方法返回对变量a中存在的数据的引用。在impl之后声明了t,以指定在program <t>上实现该方法。

解决歧义

rust编译器自动推断通用参数。下面通过一个简单的场景来理解:

let mut v = vec::new();   // creating a vector.  
v.push(10); // inserts integer value into the vector. therefore, v is of i32 type.  
println!("{:?}", v); // prints the value of v.

在上面的例子中,将整数值插入向量中。 因此,rust编译器知道向量v的类型为i32

如果删除第二行,现在代码如下所示 -

let mut v = vec::new();   // creating a vector.  
println!("{:?}", v); // prints the value of v.

上面的情况将抛出“它无法推断出t的类型”的错误。

可以通过两种方式解决上述问题:

  1. 使用以下注释:
let v : vec<bool> = vec::new();  
println!("{:?}",v) ;
  1. 使用'turbofish':: <>运算符绑定泛型参数't'
let v = vec :: <bool> :: new();  
println!("{:?}",v) ;

网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册