当前位置: 首页 > news >正文

Rust进阶-part2-泛型

Rust进阶[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>
whereT: 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>
whereT: 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
}
http://www.lryc.cn/news/608357.html

相关文章:

  • Flutter基础知识
  • 在线问诊系统源码解析:图文+视频双模式架构开发全攻略
  • CH32V单片机启用 FPU 速度测试
  • 江协科技STM32 13-1 PWR电源控制
  • 从零打造大语言模型--处理文本数据
  • FFmpeg+javacpp中纯音频播放
  • 互联网医院系统,互联网医院好处有哪些?
  • 音视频学习(四十八):PCM和WAV
  • CatBoost 完整解析:类别特征友好的梯度提升框架
  • 基于单片机智能雨刷器/汽车刮水器设计
  • zset 中特殊的操作
  • nodejs读写文件
  • 【redis】基于工业界技术分享的内容总结
  • C++ 模板初阶
  • 阿里云:Ubuntu系统部署宝塔
  • 回归预测 | Matlab实现CNN-LSTM-self-Attention多变量回归预测
  • ventoy 是一个非常棒的开源工具,可以制作多系统的usb启动盘
  • 基于落霞归雁思维框架的软件需求管理实践指南
  • Vulnhub ELECTRICAL靶机复现(附提权)
  • 计算机技术与软件专业技术资格(水平)考试简介
  • Dispersive Loss:为生成模型引入表示学习 | 如何分析kaiming新提出的dispersive loss,对扩散模型和aigc会带来什么影响?
  • 《React+TypeScript实战:前端状态管理的安全架构与性能优化深解》
  • 【Unity3D实例-功能-移动】小兵移动-通过鼠标点击进行
  • 咨询进阶——解读57页企业发展战略咨询常用工具【附全文阅读】
  • Java Optional 类教程详解
  • C++ vector底层实现与迭代器失效问题
  • 【智能体cooragent】新智能体创建相关代码解析
  • Node.js 操作 MongoDB
  • Linux系统编程Day3-- Linux常用操作(终)
  • 2025-08 安卓开发面试拷打记录(面试题)