Rust进阶[part2]_泛型

AI-摘要
sonia33 GPT
AI初始化中...
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
前往爱发电购买
Rust进阶[part2]_泛型
SoniaChenRust进阶[part2]_泛型
泛型概述
在定义函数时运用泛型,可将原本函数签名里明确指定参数和返回值类型的部分,用泛型来替代。这种方式能增强代码的适应性,为函数调用者赋予更多功能,还能避免代码重复。
fn add<T>(a:T, b:T) -> T{
a + b
}
不过,并非所有的T类型都能进行相加操作,此时会提示错误:
genertic_type.rs(5, 9): consider restricting type parameter 'T' with trait 'Add': ': std::ops::Add<Output = T>'
修正后的代码如下:
fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
a + b
}
使用场景
在函数定义中使用泛型
fn largest<T: std::cmp::PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
在结构体中使用泛型
struct Point<T> {
x: T,
y: T,
}
// 实例化泛型结构体
let integer = Point { x: 5, y: 10 };
let float = Point { x: 1.0, y: 4.0 };
在枚举里面使用泛型
enum Result<T, E> {
Ok(T),
Err(E),
}
// 实例化泛型枚举
fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {
if denominator == 0.0 {
Err("Division by zero".to_string())
} else {
Ok(numerator / denominator)
}
}
impl之后声明泛型T
泛型参数可以和结构体定义中声明的泛型参数不一样。
struct Point<T, U> {
x: T,
y: U,
}
impl<T, U> Point<T, U> {
fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
Point {
x: self.x,
y: other.y,
}
}
}
// 示例用法
let p1 = Point { x: 5, y: 10.4 };
let p2 = Point { x: "Hello", y: 'c' };
let p3 = p1.mixup(p2);
const泛型
// 定义一个固定大小的数组类型
struct ArrayBuffer<T, const N: usize> {
data: [T; N],
len: usize,
}
impl<T, const N: usize> ArrayBuffer<T, N>
where
T: Default + Copy,
{
fn new() -> Self {
ArrayBuffer {
data: [Default::default(); N],
len: 0,
}
}
}
// 创建一个可以存储10个i32的缓冲区
let buffer: ArrayBuffer<i32, 10> = ArrayBuffer::new();
where子句可以直接写在泛型参数后面,例如:
// 写法1:使用where子句
fn new_array_buffer<T, const N: usize>() -> ArrayBuffer<T, N>
where
T: Default + Copy,
{ ... }
// 写法2:直接在泛型参数后指定约束
fn new_array_buffer<T: Default + Copy, const N: usize>() -> ArrayBuffer<T, N> { ... }
泛型代码的性能
Rust通过在编译时对泛型代码进行单态化来保证效率。
当代码运行时,其执行效率和手写每个具体定义的重复代码一样。正是这个单态化过程,使得Rust泛型在运行时极为高效。
// 泛型代码
fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
a + b
}
// 单态化后的代码示例
fn add_i32(a: i32, b: i32) -> i32 {
a + b
}
fn add_f64(a: f64, b: f64) -> f64 {
a + b
}
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果