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

【Rust泛型】Rust泛型使用详解与应用场景

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Rust开发,Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:Rust语言通关之路
景天的主页:景天科技苑

在这里插入图片描述

文章目录

  • Rust泛型
    • 1. 泛型的基本概念
      • 1.1 什么是泛型
      • 1.2 为什么使用泛型
    • 2. 泛型函数
      • 2.1 基本语法
      • 2.2 实际案例:数据转换函数
      • 2.3 使用泛型函数求最大值
      • 2.4 多类型参数
    • 3. 泛型结构体和泛型方法
      • 3.1 定义泛型结构体
      • 3.2 实际案例:通用数据容器
    • 4. 泛型枚举
    • 5. 特征约束(Trait Bounds)
      • 5.1 基本特征约束
      • 5.2 多重约束
      • 5.3 where子句
    • 6. 泛型的性能
      • 6.1 零成本抽象
      • 6.2 何时使用泛型
      • 6.3 何时避免泛型

Rust泛型

泛型用于通常我们放置类型的位置,比如函数签名或结构体,允许我们创建可以代替许多具体数据类型的结构体定义。

1. 泛型的基本概念

1.1 什么是泛型

泛型(Generics)是一种编程语言特性,允许在编写代码时使用类型参数,这些参数可以在使用时被具体类型替换。Rust的泛型系统既强大又安全,能够在编译时检查所有类型约束。
泛型是一种参数化多态的形式,它允许你在定义函数、结构体、枚举和方法时使用类型参数,而不是具体的类型。

// 一个简单的泛型函数示例
fn largest<T: PartialOrd>(list: &[T]) -> &T {let mut largest = &list[0];for item in list {if item > largest {largest = item;}}largest
}

这里的<T>就是类型参数,表示这个函数可以处理任何类型T。

1.2 为什么使用泛型

代码复用:编写一次算法或数据结构,可适用于多种类型
类型安全:编译器会检查所有类型约束,避免运行时类型错误
性能:Rust的泛型是零成本抽象,编译后会生成特定类型的代码,无运行时开销
表达能力:可以精确表达接口要求和类型关系

2. 泛型函数

2.1 基本语法

泛型函数在函数名后的尖括号中声明类型参数:
声明泛型函数的时候,可以对泛型类型进行约束,T的后面加冒号,后面跟泛型约束特征,多种约束用+ 相连。满足约束特征的参数类型才能使用该泛型函数
比如在求最大值的泛型函数中,如果参数不满足比较的特征,就无法求出最大值

fn identity<T>(x: T) -> T {x
}

2.2 实际案例:数据转换函数

假设我们需要一个函数,可以将各种类型转换为字符串:
T的冒号后面,是对泛型的约束,要求泛型满足的条件,ToString,就是满足可以转换成字符串的约束。满足特征的参数类型才能使用该泛型函数

fn to_string<T: ToString>(value: T) -> String {value.to_string()
}
fn main() {println!("{}", to_string(42)); // "42"println!("{}", to_string(3.14)); // "3.14"println!("{}", to_string("hello")); // "hello"
}

在这里插入图片描述

2.3 使用泛型函数求最大值

//使用泛型函数,求最大值
fn largest<T: PartialOrd + Copy>(list: &[T]) -> &T {let mut largest = &list[0];for item in list {// 使用 PartialOrd trait 来比较元素if item > largest {// 更新最大值// 使用 Copy trait 来复制元素largest = item;}}largest
}fn main() {let number_list = vec![34, 50, 25, 1000, 65, 969];let result = largest(&number_list);println!("The largest number is: {}", result);let char_list = vec!['y', 'm', 'a', 'q', 'z', 'x', '景'];let result = largest(&char_list);println!("The largest char is: {}", result);// println!(char(result));let code = *result as u32;println!("最大字符的unicode值是: {}", code);//将字符转换为unicode值 '字符' as u32let zcode = 'z' as u32;println!("字符z的unicode值是: {}", zcode);
}

在这里插入图片描述

2.4 多类型参数

函数可以接受多个泛型参数:

//多类型参数
fn pair<T, U>(first: T, second: U) -> (T, U) {(first, second)
}fn main() {let p = pair(1, "hello");println!("p = {:?}", p);
}

在这里插入图片描述

3. 泛型结构体和泛型方法

3.1 定义泛型结构体

结构体可以使用一个或多个泛型参数:

// 泛型
// 泛型是 Rust 中的一种强大特性,它允许我们编写可以处理多种数据类型的代码。
#[derive(Debug)]
// 泛型结构体
// 允许我们定义一个结构体,它的字段可以是不同类型的
// 允许定义结构体,不使用字段
#[allow(dead_code)]
struct Pair<T, U> {first: T,second: U,
}
//泛型方法
impl<T, U> Pair<T, U> {fn new(first: T, second: U) -> Self {Pair { first, second }}//方法fn first(&self) -> &T {&self.first}fn second(&self) -> &U {&self.second}//混合类型fn create_pair<V, W>(self, other: Pair<V, W>) -> Pair<T, W> {Pair {first: self.first,second: other.second,}}
}fn main() {// 泛型结构体let p1 = Pair::new(1, "hello");println!("p1 = {:?}", p1);let p2 = Pair::new(1.0, 2.0);println!("p2 = {:?}", p2);let p3 = Pair::new("hello", vec![1, 2, 3]);println!("p3 = {:?}", p3);// 调用泛型方法println!("First element of p1: {:?}", p1.first());println!("First element of p2: {:?}", p2.first());println!("First element of p3: {:?}", p3.first());println!("Second element of p1: {:?}", p1.second());println!("Second element of p2: {:?}", p2.second());println!("Second element of p3: {:?}", p3.second());let p4 = p2.create_pair(p3);println!("p4 = {:?}", p4);}

在这里插入图片描述

注意必须在 impl 后面声明 T,U ,这样就可以在 Pair<T, U> 上实现的方法中使用它了。
在 impl 之后声明泛型 T , U,这样Rust 就知道 Point 的尖括号中的类型是泛型而不是具体类型。

泛型不能随便使用解引用
通常是因为你尝试对一个泛型 T 使用解引用操作(*),但 Rust 编译器无法确定 T 是否可以被解引用。
如果非要解引用,必须实现Deref trait
Rust 要求类型必须实现 Deref trait(或是指针类型,如 &T、Box 等)才能使用 * 解引用。如果你在泛型函数或结构体中直接尝试 *t(其中 t: T),但 T 没有约束,就会报这个错误。
type T cannot be dereferenced

解决方案

  1. 约束 T 必须实现 Deref
    使用 Deref trait 约束 T,这样 *t 才能合法使用:
use std::ops::Deref;fn print_value<T: Deref>(t: T) {println!("{}", *t); // ✅ 现在 T 必须实现 Deref
}fn main() {let x = 5;print_value(&x); // &i32 实现了 Deref,所以可以解引用
}

或者使用 where 语法:

use std::ops::Deref;fn print_value<T>(t: T)
whereT: Deref,T::Target: std::fmt::Display, // 确保解引用后的值能打印
{println!("{}", *t);
}
  1. 明确要求 T 是引用类型
    如果你希望 T 必须是一个引用(如 &i32),可以这样写:
fn print_value<T>(t: &T) // 直接接受引用
whereT: std::fmt::Display,
{println!("{}", t); // 不需要解引用,直接打印
}fn main() {let x = 5;print_value(&x); // ✅
}

3.2 实际案例:通用数据容器

实现一个可以存储任何类型的容器:

//泛型结构体
struct Container<T> {value: T,
}//泛型方法
impl<T> Container<T> {//关联函数fn new(value: T) -> Self {Self { value }}//方法// 这里的 &self 是一个引用,表示我们在方法中使用的是结构体的实例// 这里的 &T 是一个引用,表示我们返回的是一个对 value 的引用// 这里的 T 是一个泛型类型,表示我们可以使用任何类型fn get_value(&self) -> &T {&self.value}
}fn main() {let c = Container::new(42);println!("{}", c.get_value()); // 42let s = Container::new("hello");println!("{}", s.get_value()); // hellolet f = Container::new(3.14);println!("{}", f.get_value()); // 3.14let v = Container::new(vec![1, 2, 3]);println!("{:?}", v.get_value()); // [1, 2, 3]
}

在这里插入图片描述

4. 泛型枚举

Rust的标准库中有许多使用泛型的枚举,最著名的就是Option和Result:

//泛型枚举
enum Option<T> {Some(T),None,
}enum Result<T, E> {Ok(T),Err(E),
}fn main() {// 使用泛型枚举的Some和Oklet x: Option<i32> = Option::Some(5);let y: Result<i32, String> = Result::Ok(10);match x {Option::Some(value) => println!("Option has value: {}", value),Option::None => println!("Option is None"),}match y {Result::Ok(value) => println!("Result is Ok with value: {}", value),Result::Err(err) => println!("Result is Err with error: {}", err),}// 使用泛型枚举的None和Errlet z: Option<i32> = Option::None;match z {Option::Some(value) => println!("Option has value: {}", value),Option::None => println!("Option is None"),}let w: Result<i32, String> = Result::Err("An error occurred".to_string());match w {Result::Ok(value) => println!("Result is Ok with value: {}", value),Result::Err(err) => println!("Result is Err with error: {}", err),}
}

在这里插入图片描述

5. 特征约束(Trait Bounds)

声明泛型函数的时候,可以对泛型类型进行约束,T的后面加冒号,后面跟泛型约束特征,多种约束用+ 相连。满足约束特征的参数类型才能使用该泛型函数

5.1 基本特征约束

符合特征约束的参数,才能成功调用该函数

fn print_debug<T: std::fmt::Debug>(value: T) {println!("{:?}", value);
}

5.2 多重约束

使用+符号指定多个特征约束:

fn clone_and_print<T: Clone + std::fmt::Debug>(value: T) {let cloned = value.clone();println!("{:?}", cloned);
}

5.3 where子句

一般的约束,只需要在T后面的冒号后加上约束即可,对于复杂的约束,可以使用where子句提高可读性:

//where子句
fn complex_function<T, U>(t: T, u: U) -> i32where T: std::fmt::Display + Clone, U: Clone + std::fmt::Debug
{// 函数实现println!("t = {}", t);println!("u = {:?}", u);// 返回一个整数42
}

在这里插入图片描述

6. 泛型的性能

6.1 零成本抽象

Rust 实现泛型的方式意味着你的代码使用泛型类型参数,相比指定具体类型并没有任何速度上的损失!
Rust 通过在编译时进行泛型代码的 单态化(monomorphization)来保证效率。
单态化是一个将泛型代码转变为实际放入的具体类型的特定代码的过程。

这意味着:
运行时没有类型检查开销
生成的代码与手写特定类型代码一样高效
但可能导致代码膨胀(更大的二进制文件)

让我们看看一个使用标准库中 Option 枚举的例子:

let integer = Some(5);
let float = Some(5.0);

当 Rust 编译这些代码的时候,它会进行单态化。编译器会读取传递给 Option 的值并发现有两种 Option<T> :一个对应i32 另一个对应 f64 。
为此,它会将泛型定义 Option 展开为 Option_i32 和 Option_f64 ,接着将泛型定义替换为这两个具体的定义。

6.2 何时使用泛型

算法需要在多种类型上工作:如排序、搜索等
数据结构需要存储不同类型:如Vec、Option等
需要类型安全的多态行为:避免使用dyn trait带来的运行时开销

6.3 何时避免泛型

只有少数具体类型:可能不值得增加复杂性
性能不是关键因素:可以考虑使用trait对象
导致过于复杂的类型签名:可能影响代码可读性

相关文章:

【Rust泛型】Rust泛型使用详解与应用场景

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

一周学完计算机网络之三:1、数据链路层概述

简单的概述 数据链路层是计算机网络体系结构中的第二层&#xff0c;它在物理层提供的基本服务基础上&#xff0c;负责将数据从一个节点可靠地传输到相邻节点。可以将其想象成一个负责在两个相邻的网络设备之间进行数据 “搬运” 和 “整理” 的 “快递中转站”。 几个重要概念…...

配置ssh无密登录

在root下有一个.ssh文件夹&#xff0c;它的下面有一个known_hosts文件&#xff0c;这个里面记录了哪些其他的主机通过ssh访问过当前的主机。 免密登录原理 &#xff08;2&#xff09;生成公钥和私钥 具体操作&#xff1a; 1. 进入 hadoop1001 2. 运行命令&#xff1a;ssh-keyg…...

南京邮电大学金工实习答案

一、金工实习的定义 金工实习是机械类专业学生一项重要的实践课程&#xff0c;它绝非仅仅只是理论知识在操作层面的简单验证&#xff0c;而是一个全方位培养学生综合实践能力与职业素养的系统工程。从本质上而言&#xff0c;金工实习是学生走出教室&#xff0c;亲身踏入机械加…...

无偿帮写毕业论文

以下教程教你如何利用相关网站和AI免费帮你写一个毕业论文。毕竟毕业论文只要过就行&#xff0c;脱产学习这么多年&#xff0c;终于熬出头了&#xff0c;完成毕设后有空就去多看看亲人好友&#xff0c;祝好&#xff01; 一、找一个论文模板(最好是overleaf) 废话不多说&#…...

【高数上册笔记01】:从集合映射到区间函数

【参考资料】 同济大学《高等数学》教材樊顺厚老师B站《高等数学精讲》系列课程 &#xff08;注&#xff1a;本笔记为个人数学复习资料&#xff0c;旨在通过系统化整理替代厚重教材&#xff0c;便于随时查阅与巩固知识要点&#xff09; 仅用于个人数学复习&#xff0c;因为课…...

大数据从专家到小白

文章目录 数据湖技术Apache Iceberg FlinkHiveHadoopHDFS 数据湖技术 Apache Iceberg Iceberg是一个通用的表格式&#xff08;数据组织格式&#xff09;&#xff0c;它可以适配Presto&#xff0c;Spark等引擎提供高性能的读写和元数据管理功能。 Flink Hive Hadoop HDFS...

特励达力科LeCroy推出Xena Freya Z800 800GE高性能的800G以太网测试平台

Xena Freya Z800 800GE 是由全球领先的测试与测量解决方案提供商特励达力科公司&#xff08;Teledyne LeCroy&#xff09;开发的高性能以太网测试平台&#xff0c;专为满足从10GE到800GE数据中心互连速度的需求而设计。特励达力科公司在网络测试领域拥有超过50年的技术积累&…...

LeetCode 热题 100 98. 验证二叉搜索树

LeetCode 热题 100 | 98. 验证二叉搜索树 大家好&#xff0c;今天我们来解决一道经典的二叉树问题——验证二叉搜索树。这道题在 LeetCode 上被标记为中等难度&#xff0c;要求判断给定的二叉树是否是一个有效的二叉搜索树&#xff08;BST&#xff09;。 问题描述 给你一个二…...

Linux文件编程——open函数

在 Linux 系统中&#xff0c;文件操作不仅仅通过高级语言的标准库进行&#xff0c;底层的文件操作是通过 系统调用 来实现的。系统调用 是用户空间与操作系统内核之间的接口&#xff0c;允许程序请求操作系统提供的服务&#xff0c;包括文件读写、内存管理、进程控制等。本文将…...

Linux-Ext系列文件系统

1.理解硬件 1.1磁盘 机械磁盘是计算机中唯⼀的⼀个机械设备 磁盘---外设 慢 容量⼤&#xff0c;价格便宜 1.2磁盘的物理结构 1.3磁盘的存储结构 扇区&#xff1a;是磁盘存储数据的基本单位&#xff0c;512字节&#xff0c;块设备 如何定位⼀个扇区呢&#xff1f; 可以先定…...

Multisim14使用教程详尽版--(2025最新版)

一、Multisim14前言 1.1、主流电路仿真软件 1. Multisim&#xff1a;NI开发的SPICE标准仿真工具&#xff0c;支持模拟/数字电路混合仿真&#xff0c;内置丰富的元件库和虚拟仪器&#xff08;示波器、频谱仪等&#xff09;&#xff0c;适合教学和竞赛设计。官网&#xff1a;艾…...

C——猜数字游戏

前面我们已经学习了C语言常见概念&#xff0c;数据类型和变量以及分置于循环的内容&#xff0c;现在我们可以将这些内容结合起来写一个有趣的小游戏。下面正式开始我们今天的主题——猜数字游戏的实现。 猜数字游戏的要求&#xff1a; 1.电脑自动生成1~100的随机数。 2.玩家…...

【iOS】SDWebImage源码学习

SDWebImage源码学习 文章目录 SDWebImage源码学习前言SDWebImage缓存流程sd_setImageWithURL(UIImageViewWebCache层)sd_internalSetImageWithURL(UIViewWebCache层)loadImageWithURL(SDWebManger层)queryCacheOperationForKey(SDImageCache层)删除缓存 callDownloadProcessFor…...

.Net HttpClient 处理响应数据

HttpClient 处理响应数据 1、初始化及全局设置 //初始化&#xff1a;必须先执行一次 #!import ./ini.ipynb2、处理响应状态 //判断响应码&#xff1a;正常 {var response await SharedClient.GetAsync("api/Normal/GetAccount?id1");if(response.StatusCode Sy…...

【心海资源】【最新话费盗u】【未测】提币对方官方波场+没有任何加密+无后门+前端VUE

提笔接口请使用官方提笔&#xff0c;第三方提笔都有风险 后门你们也扫扫&#xff0c;这种源码风险大&#xff0c;自己玩玩学习进行了 重要的事情说三遍 &#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…...

Python中的标识、相等性与别名:深入理解对象引用机制

在Python编程中&#xff0c;理解变量如何引用对象以及对象之间的比较方式是至关重要的基础概念。本文将通过Lewis Carroll的笔名示例&#xff0c;深入探讨Python中的对象标识、相等性判断以及别名机制。 别名现象&#xff1a;变量共享同一对象 >>> charles {name: …...

Java 1.8(也称为Java 8)

Java 1.8&#xff08;也称为Java 8&#xff09;是Oracle于2014年发布的一个重要版本&#xff0c;引入了许多新特性和改进&#xff0c;极大地提升了Java语言的表达力和开发效率。以下是Java 1.8的主要新特性&#xff1a; ### 1. Lambda表达式 Lambda表达式是Java 1.8最具革命性…...

LVGL简易计算器实战

文章目录 &#x1f4c1; 文件结构建议&#x1f539; eval.h 表达式求值头文件&#x1f539; eval.c 表达式求值实现文件&#xff08;带详细注释&#xff09;&#x1f539; ui.h 界面头文件&#x1f539; ui.c 界面实现文件&#x1f539; main.c 主函数入口✅ 总结 项目效果&…...

Linux | Uboot-Logo 修改文档(第十七天)

01 Uboot 修改 首先我们在 home 目录下新建一个文件夹 imx6ull,然后打开 i.MX6ULL 终结者光盘资料\05_uboot linux源码,在 window 下解压下图箭头所指的压缩包,解压后分别得到 linux-imx-rel_imx_4.1.15_2.1.0_ga_20200323.tar.gz 和 uboot-imx-rel_imx_4.1.15_2.1.0_…...

数字孪生概念

数字孪生&#xff08;Digital Twin&#xff09; 是指通过数字技术对物理实体&#xff08;如设备、系统、流程或环境&#xff09;进行高保真建模和实时动态映射&#xff0c;实现虚实交互、仿真预测和优化决策的技术体系。它是工业4.0、智慧城市和数字化转型的核心技术之一。 1. …...

c++STL-string的使用

这里写自定义目录标题 string的使用string写成类模板的原因string的版本举例构造、析构函数和赋值重载构造函数和析构函数operator Iterators迭代器begin和endrbegin和rendcbegin和cend&#xff0c;crbegin和crend&#xff08;c11&#xff09; capacity容量有关函数不同编译器下…...

总结C/C++中程序内存区域划分

C/C程序内存分配的⼏个区域 1..栈区&#xff08;stack&#xff09;&#xff1a;在执⾏函数时&#xff0c;函数内局部变量的存储单元都可以在栈上创建&#xff0c;函数执⾏结束时 这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中&#xff0c;效率很⾼&#xff0c…...

C# 方法(方法重载)

本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 方法重载 一个类中可以有多个…...

Dockerfile 完全指南:从入门到最佳实践

Dockerfile 完全指南&#xff1a;从入门到最佳实践 1. Dockerfile 简介与作用 Dockerfile 是一个文本文件&#xff0c;包含了一系列用于构建 Docker 镜像的指令。它允许开发者通过简单的指令定义镜像的构建过程&#xff0c;实现自动化、可重复的镜像构建。 主要作用&#xf…...

DEEPPOLAR:通过深度学习发明非线性大核极坐标码(2)

目录 2.问题的提出和背景 2.1 信道编码 2.2.极化码 极坐标编码 极坐标解码 原文&#xff1a;《DEEPPOLAR: Inventing Nonlinear Large-Kernel Polar Codes via Deep Learning》 2.问题的提出和背景 2.1 信道编码 信道编码是一种为传输添加冗余的技术&#xff0c;使其对…...

ESP32-S3 学习笔记(1)

ESP32-S3 学习笔记&#xff08;1&#xff09; 背景环境添加工程文件材料准备轻触开关的正负极 背景 ​ 闲来无事&#xff0c;看到立创论坛上有许多大佬开源的项目&#xff0c;甚是厉害&#xff0c;于是决定自己也来搞一搞&#xff0c;同时可以做一些技术积累&#xff0c;看了很…...

Python Cookbook-7.9 访问 MySQL 数据库

任务 想访问一个 MySQL 数据库。 解决方案 MySQLdb 模块正是为这种任务而设计的: import MySQLdb #创建一个连接对象,再用它创建游标 con = MySQLdb.connect(host = "127.0.0.1", port = 3306, user = "joe",<...

docker安装superset实践

1、拉取docker镜像 docker pull apache/superset:latest 2、安装superset容器 mkdir /usr/local/develop/docker/superset/ -p touch /usr/local/develop/docker/superset/superset_config.py superset_config.py配置文件如下&#xff1a; SQLALCHEMY_DATABASE_URI mysql:…...

Web开发—Vue工程化

文章目录 前言 Vue工程化 一、介绍 二、环境准备 1.介绍create-vue 2.NodeJS安装 3.npm介绍 三&#xff0c;Vue项目创建 四&#xff0c;项目结构 五&#xff0c;启动项目 六&#xff0c;Vue项目开发流程 七&#xff0c;API风格 前言 Vue工程化 前面我们在介绍Vue的时候&#…...

什么是硬件中断请求号?什么是中断向量号?

一、硬件中断请求号&#xff08;IRQ&#xff0c;Interrupt Request Number&#xff09; ​定义​&#xff1a; 硬件中断请求号&#xff08;IRQ&#xff09;是硬件设备向CPU发送中断请求时使用的唯一标识符&#xff0c;用于区分不同的中断源。例如&#xff0c;键盘、硬盘等外设…...

[Java实战]Spring Boot 定时任务(十五)

[Java实战]Spring Boot 定时任务&#xff08;十五&#xff09; 一、定时任务的应用场景 数据同步&#xff1a;每日凌晨同步第三方数据状态检查&#xff1a;每5分钟扫描订单超时未支付资源清理&#xff1a;每小时清理临时文件报表生成&#xff1a;每月1号生成财务统计报表通知…...

OpenWrt开发第7篇:OpenWrt配置支持Web界面

文/指尖动听知识库-谷谷 文章为付费内容,商业行为,禁止私自转载及抄袭,违者必究!!! 文章专栏:Openwrt开发-基于Raspberry Pi 4B开发板 OpenWrt的luci是一个基于Web的图形化管理界面,为用户提供了直观的操作方式,无需命令行即可完成大部分功能的配置。 1.在终端输入ma…...

【多模态】IMAGEBIND论文阅读

every blog every motto: Although the world is full of suffering&#xff0c; it is full also of the overcoming of it 0. 前言 IMAGEBIND 多模态论文梗概 IMAGEBIND是一种夸模态的神经网络&#xff0c;以图片为中心&#xff0c;联合六中模态的网络&#xff08;图片、文…...

【C语言干货】二维数组传参本质

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、二维数组的内存布局 1.二维数组的实质2.二维数组的地址关系 二、二维数组传参的本质 1.参数传递的退化机制2.三种等效的函数声明方式 总结 前言 提示&#…...

基于SpringBoot的抽奖系统测试报告

一、编写目的 本报告为抽奖系统测试报告&#xff0c;本项目可用于团体抽奖活动&#xff0c;包括了用户注册&#xff0c;用户登录&#xff0c;修改奖项以及抽奖等功能。 二、项目背景 抽奖系统采用前后端分离的方法来实现&#xff0c;同时使用了数据库来存储相关的数据&…...

Go语言从零构建SQL数据库(9)-数据库优化器的双剑客

数据库优化器的双剑客&#xff1a;谓词下推与列裁剪 在数据库查询优化的世界里&#xff0c;有两位特别重要的"超级英雄"&#xff1a;谓词下推和列裁剪。这两种优化技术虽然简单&#xff0c;却能带来惊人的性能提升。今天&#xff0c;我们就来揭开它们的神秘面纱&…...

C++中什么是函数指针?

在C中&#xff0c;函数指针是一个指向函数的指针变量。通过函数指针&#xff0c;我们可以像使用函数一样调用它所指向的函数&#xff0c;常用于实现回调函数、函数指针数组等功能。 以下是一个简单的C代码示例&#xff0c;展示了函数指针的使用&#xff1a; cpp #include <…...

Python工具链UV整合环境管理

Python工具链UV整合环境管理 终极Python工具链UV&#xff1a;从依赖管理到项目开发的全维度解析一、引言&#xff1a;重新定义Python开发的大一统时代二、深度安装指南&#xff1a;多场景适配方案1. 官方独立安装器&#xff08;推荐方案&#xff09;2. 进阶安装方式3. 安装验证…...

RuoYi-v4.7.8 jar/war部署

准备条件 jdk-8u73-windows-x64.exe mysql5.7 apache-tomcat-9.0.60 apache-maven-3.8.1 RuoYi-v4.7.8.zip &#xff08;官网 RuoYi&#xff09; 登录gitee,选择标签要下载的版本好&#xff0c;点击克隆下载zip压缩文件 安装maven Apache Archive Distribution Directory…...

基于SpringBoot的小区停车位管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

张量并行优质博客

必读图解系列1 比较全面的相关文献总结博客&#xff0c;可以重点看一下其中的行列切分算子2 # 图解大模型训练之&#xff1a;张量模型并行(TP)&#xff0c;Megatron-LM ↩︎ # 大规模分布式 AI 模型训练系列——张量并行 ↩︎...

汽车诊断简介

历史 20世纪80年代&#xff0c;由于美国西海岸严重的雾霾问题&#xff0c;CARB&#xff08;加州空气资源委员会&#xff09;通过了一项法律&#xff0c;要求对机动车辆进行车载监测诊断。这推动了OBD-I的引入&#xff0c;并在1990年代被OBD II取代。与此同时&#xff0c;欧洲也…...

suricata之规则去重

一、环境和背景 1.1 环境 OS: Ubuntu 22.04.5 LTS IDE: vscode suricata: suricata 7.0.5 1.2 背景 在添加规则时&#xff0c;为了给规则分类&#xff0c;将不同类别的规则写入不同的文件。 在规则加载时两条不同的规则却被认为是重复的&#xff0c;因此记录一下去重逻辑。…...

接口在函数参数和对象类型中的应用

在 TypeScript 中&#xff0c;接口&#xff08;interface&#xff09;是一种强大的工具&#xff0c;用于定义和约束对象的结构。它不仅可以用于描述对象类型&#xff0c;还能够用于定义函数的参数和返回类型。接口可以提高代码的可读性、可维护性&#xff0c;并帮助捕捉潜在的错…...

Javascript:数组和函数

数组 创建数组 使用new创建 let arrnew array(数组大小); 直接赋值创建 let Arr2[];let Arr3[1,A,"HELLLO"]; 这里JS的数组里面的元素属性可以各不相同 演示代码 <script>let Arr1new Array(5);let Arr2[];let Arr3[1,A,"HELLLO"];console.…...

Vue Router

Vue Router:前端路由跳转的魔法 什么是Vue Router Vue Router是Vue官方的路由管理器,它允许我们在不重新加载页面的情况下更改浏览器中显示的内容,实现单页应用(SPA)的无缝导航体验。 📊 Vue Router工作流程图 #mermaid-svg-xNtkA0qYMjB0lvUt {font-family:"trebu…...

谷歌与微软的AI战争:搜索、云服务与生态布局

谷歌与微软的AI战争&#xff1a;搜索、云服务与生态布局 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 谷歌与微软的AI战争&#xff1a;搜索、云服务与生态布局摘要引言技术路线对比1. AI基础设施&#xff1a;算力…...

robomaster机甲大师--电调电机

文章目录 C620电调ID设置速率 电调发送报文电调接收报文cubemx程序初始化发送接收 C620电调 ID设置 速率 1Mbps 电调发送报文 发送的数据为控制电机的输出电流&#xff0c;需要将can数据帧的ID设置为0x200 电调接收报文 机械角度&#xff1a;电机的0到360度映射到0到几千转…...

菜鸟之路day31一一MySQL之多表设计

菜鸟之路day31一一MySQL之多表设计 作者&#xff1a;blue 时间&#xff1a;2025.5.9 文章目录 菜鸟之路day31一一MySQL之多表设计0.概述一.多表设计1.1一对多1.2一对一1.3多对多 0.概述 内容学习自黑马程序员BV1m84y1w7Tb 一.多表设计 1.1一对多 一对多关系实现&#xff…...