当要创建多种形式的功能时,即,函数的参数可以接受多种类型的数据。 这可以通过泛型来实现。 泛型也称为“参数多态”,其中多态是多重的,而变形是形式。
有两种方法可以提供通用代码:
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'
可以是任何类型,即i32
,bool
,f64
或char
。 但是,如果左侧的类型与右侧的值不匹配,则会发生错误。 如下示例:
let x : option<i32> = some(10.8);
在上述情况下,左侧的类型是i32
,右侧的值是f64
类型。 因此,错误发生“类型不匹配”。
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>
结构在一种类型上是通用的,而a
和b
是相同类型的。创建两个实例integer
和float
。 integer
包含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>
在一种类型上是通用的,而a
和b
是相同类型的。创建了一个c
的实例。c
包含不同类型的值,即i32
和f64
。 因此,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的类型”的错误。
可以通过两种方式解决上述问题:
let v : vec<bool> = vec::new();
println!("{:?}",v) ;
'turbofish':: <>
运算符绑定泛型参数't'
:let v = vec :: <bool> :: new();
println!("{:?}",v) ;