【Rust模式与匹配】Rust模式与匹配深入探索与应用实战
✨✨ 欢迎大家来到景天科技苑✨✨
🎈🎈 养成好习惯,先赞后看哦~🎈🎈
🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Rust开发,Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。所属的专栏:Rust语言通关之路
景天的主页:景天科技苑
文章目录
- Rust模式和匹配
- 一、 模式匹配基础
- 1.1 什么是模式匹配
- 1.2 基本match表达式
- 1.3 模式匹配的穷尽性检查
- 1.4 let 语句
- 1.5 函数参数
- 二、Refutability(可反驳性): 模式是否会匹配失效
- 三、模式匹配的各种形式
- 3.1 字面量匹配
- 3.2 匹配命名变量
- 3.3 匹配多个模式
- 3.4 变量绑定
- 3.5 解构匹配
- 3.6 引用匹配
- 3.7 模式守卫
- 3.8 if let 、while let和for循环
- 3.8.1 if let 简洁匹配
- 3.8.2 while let 条件循环
- 3.8.3 for循环
- 四、高级模式匹配技巧
- 4.1 忽略模式中的值
- 4.1.1 忽略模式部分
- 4.1.2 使用 _ 忽略整个值
- 4.2 匹配守卫与绑定
- 五、总结
Rust模式和匹配
模式是 Rust 中特殊的语法,它用来匹配类型中的结构,无论类型是简单还是复杂。
结合使用模式和 match 表达式以及其他结构可以提供更多对程序控制流的支配权。模式由如下一些内容组合而成:
字面量
解构的数组、枚举、结构体或者元组
变量
通配符
占位符
这些部分描述了我们要处理的数据的形状,接着可以用其匹配值来决定程序是否拥有正确的数据来运行特定部分的代码。
我们通过将一些值与模式相比较来使用它。如果模式匹配这些值,我们对值部分进行相应处理。
本文是所有模式相关内容的参考。我们将涉及到使用模式的有效位置,refutable 与 irrefutable 模式的区别,和你可能会见到的不同类型的模式语法。
在最后,你将会看到如何使用模式创建强大而简洁的代码。
一、 模式匹配基础
1.1 什么是模式匹配
模式匹配是Rust语言中一种强大的控制流结构,它允许你根据数据的形状来检查数据并相应地执行代码。
与传统的if-else语句不同,模式匹配提供了更清晰、更安全的方式来处理多种可能的数据状态。
在Rust中,模式匹配主要通过match表达式和if let/while let结构来实现。这些结构不仅简洁明了,还能在编译时检查所有可能的情况,避免遗漏处理某些情形。
1.2 基本match表达式
最基本的模式匹配形式是match表达式,它类似于其他语言中的switch语句,但功能更强大。
let number = 13;match number {1 => println!("One"),2 | 3 | 5 | 7 | 11 => println!("This is a prime"),13..=19 => println!("A teen"),_ => println!("Ain't special"),
}
在这个例子中:
1匹配精确值1
2 | 3 | 5 | 7 | 11使用|表示"或"关系 属于多个模式匹配
13…=19匹配13到19的闭区间范围 通过 …= 匹配值的范围 …= 语法允许你匹配一个闭区间范围内的值。
_
是通配符模式,匹配任何值 我们已经使用过下划线(_)作为匹配但不绑定任何值的通配符模式了。
1.3 模式匹配的穷尽性检查
Rust编译器强制要求match表达式必须覆盖所有可能的情况。这种穷尽性检查是Rust安全保证的重要组成部分。
#[allow(dead_code)]
enum Direction {North,South,East,West,
}fn main() {let dir = Direction::North;match dir {Direction::North => println!("Heading north"),Direction::South => println!("Heading south"),Direction::East => println!("Heading east"),Direction::West => println!("Heading west"),// 如果注释掉任何一个分支,编译器会报错}
}
1.4 let 语句
let语句的模式是:let PATTERN = EXPRESSION;
像 let x = 5; 这样的语句中变量名位于 PATTERN 位置,变量名不过是形式特别朴素的模式。
我们将表达式与模式比较,并为任何找到的名称赋值。所以例如 let x = 5; 的情况,x 是一个表示“将匹配到的值绑定到变量 x” 的模式。
同时因为名称 x 是整个模式,这个模式实际上等于 “将任何值绑定到变量 x,不管值是什么”。
为了更清楚的理解 let 的模式匹配方面的内容,使用 let 和模式解构一个元组:
let (x, y, z) = (1, 2, 3);
这里将一个元组与模式匹配。Rust 会比较值 (1, 2, 3) 与模式 (x, y, z) 并发现此值匹配这个模式。
在这个例子中,将会把 1 绑定到 x,2 绑定到 y 并将 3 绑定到 z。你可以将这个元组模式看作是将三个独立的变量模式结合在一起。
如果模式中元素的数量不匹配元组中元素的数量,则整个类型不匹配,并会得到一个编译时错误。
例如,如下示例展示了尝试用两个变量解构三个元素的元组,这是不行的:
let (x, y) = (1, 2, 3);
1.5 函数参数
函数参数也可以是模式。
fn foo(x: i32) {// 代码
}
x 部分就是一个模式!类似于之前对 let 所做的,可以在函数参数中匹配元组。如下列表将传递给函数的元组拆分为值:
fn print_coordinates(&(x, y): &(i32, i32)) {println!("Current location: ({}, {})", x, y);
}fn main() {let point = (3, 5);print_coordinates(&point);
}
这打印出 Current location: (3, 5)。值 &(3, 5) 会匹配模式 &(x, y),如此 x 得到了值 3,而 y得到了值 5。
因为如闭包类似于函数,也可以在闭包参数列表中使用模式。
现在我们见过了很多使用模式的方式了,不过模式在每个使用它的地方并不以相同的方式工作;在一些地方,模式必须是 irrefutable 的,意味着他们必须匹配所提供的任何值。
在另一些情况,他们则可以是 refutable 的。接下来让我们讨论这两个概念。
二、Refutability(可反驳性): 模式是否会匹配失效
模式有两种形式:refutable(可反驳的)和 irrefutable(不可反驳的)。
能匹配任何传递的可能值的模式被称为是 不可反驳的(irrefutable)。
一个例子就是 let x = 5; 语句中的 x,因为 x 可以匹配任何值所以不可能会失败。
对某些可能的值进行匹配会失败的模式被称为是 可反驳的(refutable)。
一个这样的例子便是 if let Some(x) = a_value 表达式中的 Some(x);如果变量 a_value 中的值是 None 而不是 Some,那么 Some(x) 模式不能匹配。
函数参数、 let 语句和 for 循环只能接受不可反驳的模式,因为通过不匹配的值程序无法进行有意义的工作。
if let 和 while let 表达式被限制为只能接受可反驳的模式,因为根据定义他们意在处理可能的失败:条件表达式的功能就是根据成功或失败执行不同的操作。
通常我们无需担心可反驳和不可反驳模式的区别,不过确实需要熟悉可反驳性的概念,这样当在错误信息中看到时就知道如何应对。
遇到这些情况,根据代码行为的意图,需要修改模式或者使用模式的结构。
match 匹配分支必须使用可反驳模式,除了最后一个分支需要使用能匹配任何剩余值的不可反驳模式。
Rust 允许我们在只有一个匹配分支的 match 中使用不可反驳模式,不过这么做不是特别有用,并可以被更简单的 let 语句替代。
//模式匹配中的可反驳模式和不可反驳模式fn main() {//let语句、函数参数和for循环中的模式必须是不可反驳的let x = 5; //不可反驳模式let y: Option<i32> = Some(5); //不可反驳模式//可反驳模式不能用let来定义// let Some(z) = y; //可反驳模式//可以使用if let或者while let来处理可反驳模式if let Some(z) = y {println!("z: {}", z);}//如果if let用于处理不可反驳模式,编译器会警告if let x = 5 {println!("x: {}", x);}
}
三、模式匹配的各种形式
3.1 字面量匹配
最简单的模式是直接匹配字面量值:
let x = 1;match x {1 => println!("one"),2 => println!("two"),3 => println!("three"),_ => println!("anything"),
}
3.2 匹配命名变量
名变量是匹配任何值的不可反驳模式,这在之前已经使用过数次。
然而当其用于 match 表达式时情况会有些复杂。因为 match 会开始一个新作用域,match 表达式中作为模式的一部分声明的变量会覆盖 match 结构之外的同名变量,与所有变量一样。
fn main() {let x = Some(5);let y = 10;match x {Some(50) => println!("Got 50"),Some(y) => println!("Matched, y = {:?}", y),_ => println!("Default case, x = {:?}", x),}println!("at the end: x = {:?}, y = {:?}", x, y);
}
让我们看看当 match 语句运行的时候发生了什么。第一个匹配分支的模式并不匹配 x 中定义的值,所以代码继续执行。
第二个匹配分支中的模式引入了一个新变量 y,它会匹配任何 Some 中的值。
因为我们在 match 表达式的新作用域中,这是一个新变量,而不是开头声明为值 10 的那个 y。
这个新的 y 绑定会匹配任何 Some 中的值,在这里是 x 中的值。
因此这个 y 绑定了 x 中 Some 内部的值。这个值是 5,所以这个分支的表达式将会执行并打印出 Matched, y = 5。
如果 x 的值是 None 而不是 Some(5),头两个分支的模式不会匹配,所以会匹配下划线。
这个分支的模式中没有引入变量 x,所以此时表达式中的 x 会是外部没有被覆盖的 x。在这个假想的例子中,match 将会打印 Default case, x = None。
一旦 match 表达式执行完毕,其作用域也就结束了,同理内部 y 的作用域也结束了。最后的 println! 会打印 at the end: x = Some(5), y = 10。
为了创建能够比较外部 x 和 y 的值,而不引入覆盖变量的 match 表达式,我们需要相应地使用带有条件的匹配守卫(match guard)。
我们稍后将在 “匹配守卫提供的额外条件” 这一小节讨论匹配守卫。
3.3 匹配多个模式
在 match 表达式中,可以使用 | 语法匹配多个模式,它代表 或(or)的意思。
例如,如下代码将 x 的值与匹配分支相比较,第一个分支有 或 选项,意味着如果 x 的值匹配此分支的任一个值,它就会运行:
fn main() {let x = 1;match x {1 | 2 => println!("one or two"),3 => println!("three"),_ => println!("anything"),}
}
3.4 变量绑定
@ 绑定
at 运算符(@)允许我们在创建一个存放值的变量的同时测试其值是否匹配模式。
如下示例展示了一个例子,这里我们希望测试 Message::Hello 的 id 字段是否位于 3…=7 范围内,同时也希望能将其值绑定到 id_variable 变量中以便此分支相关联的代码可以使用它。
可以将 id_variable 命名为 id,与字段同名,不过出于示例的目的这里选择了不同的名称。
模式可以绑定变量,这使得我们可以在匹配的同时提取值:
fn main() {enum Message {Hello {id: i32,},}let msg = Message::Hello { id: 5 };match msg {//将id绑定到变量id_variable上//@指定匹配的范围Message::Hello { id: id_variable @ 3..=7 } => {println!("Found an id in range: {}", id_variable)}Message::Hello { id: 10..=12 } => { println!("Found an id in another range") }Message::Hello { id } => { println!("Found some other id: {}", id) }}
}
3.5 解构匹配
模式匹配最强大的功能之一是能够解构复杂的数据类型:
解构元组
fn main() {let pair = (0, -2);//解构元组match pair {(0, y) => println!("First is 0, y is {}", y),(x, 0) => println!("x is {}, second is 0", x),_ => println!("No zero"),}
}
解构结构体
fn main() {struct Point {x: i32,y: i32,}let point = Point { x: 0, y: 7 };match point {Point { x, y: 0 } => println!("On the x axis at {}", x),Point { x: 0, y } => println!("On the y axis at {}", y),Point { x, y } => println!("On neither axis: ({}, {})", x, y),}
}
解构枚举
#[allow(dead_code)]
enum Message {Quit,Move {x: i32,y: i32,},Write(String),ChangeColor(i32, i32, i32),
}
fn main() {//创建枚举对象let msg = Message::ChangeColor(0, 160, 255);//根据枚举对象,来匹配枚举match msg {Message::Quit => println!("Quit"),Message::Move { x, y } => println!("Move to x: {}, y: {}", x, y),Message::Write(text) => println!("Text message: {}", text),Message::ChangeColor(r, g, b) => println!("Change color to RGB: {}, {}, {}", r, g, b),}
}
解构嵌套的结构体和枚举
enum Color {Rgb(i32, i32, i32),Hsv(i32, i32, i32),
}enum Message {Quit,Move {x: i32,y: i32,},Write(String),ChangeColor(Color),
}fn main() {let msg = Message::ChangeColor(Color::Hsv(0, 160, 255));//其他的我们都不关心,我们只匹配ChangeColormatch msg {Message::ChangeColor(Color::Rgb(r, g, b)) => {println!("rgb red {}, green {}, and blue {}", r, g, b)}Message::ChangeColor(Color::Hsv(h, s, v)) => {println!("hsv to hue {}, saturation {}, and value {}", h, s, v)}_ => (),}
}
3.6 引用匹配
当匹配引用时,需要使用&来解构:
fn main() {let reference = &4;match reference {&val => println!("Got a value via destructuring: {}", val),}// 更简单的方式是使用解引用match *reference {val => println!("Got a value via dereferencing: {}", val),}
}
3.7 模式守卫
匹配守卫(match guard)是一个指定于 match 分支模式之后的额外 if 条件,它也必须被满足才能选择此分支。匹配守卫用于表达比单独的模式所能允许的更为复杂的情况。
模式守卫允许在模式匹配中添加额外的条件:
fn main() {let pair = (2, -2);match pair {//匹配后面跟if条件判断(x, y) if x == y => println!("These are twins"),(x, y) if x + y == 0 => println!("Antimatter, kaboom!"),(x, _) if x % 2 == 1 => println!("The first one is odd"),_ => println!("No correlation"),}
}
3.8 if let 、while let和for循环
3.8.1 if let 简洁匹配
if let提供了一种更简洁的方式来处理只关心一种模式而忽略其他模式的情况:
fn main() {let some_value = Some(3);// 使用matchmatch some_value {Some(3) => println!("three"),_ => (),}// 使用if let更简洁if let Some(3) = some_value {println!("three");}
}
3.8.2 while let 条件循环
while let使得只要模式匹配就一直循环:
fn main() {let mut stack = Vec::new();stack.push(1);stack.push(2);stack.push(3);//使用while let来处理Option类型//只要stack.pop()返回Some,就执行循环体while let Some(top) = stack.pop() {println!("{}", top);}
}
3.8.3 for循环
for 循环是 Rust 中最常见的循环结构,不过还没有讲到的是 for 可以获取一个模式。
在 for 循环中,模式是 for 关键字直接跟随的值,正如 for x in y 中的 x。
fn main() {let v = vec!['a', 'b', 'c'];//通过for循环来遍历vector生成的迭代器for (index, value) in v.iter().enumerate() {println!("{} is at index {}", value, index);}
}
这里使用 enumerate 方法适配一个迭代器来产生一个值和其在迭代器中的索引,他们位于一个元组中。
第一个 enumerate 调用会产生元组 (0, ‘a’)。当这个值匹配模式 (index, value),index 将会是 0 而 value 将会是 ‘a’,并打印出第一行输出。以此类推。
四、高级模式匹配技巧
4.1 忽略模式中的值
4.1.1 忽略模式部分
对于有多个部分的值,可以使用 … 语法来只使用部分并忽略其它值,同时避免不得不每一个忽略值列出下划线。… 模式会忽略模式中剩余的任何没有显式匹配的值部分。
可以使用_或…来忽略值的部分:
#[allow(dead_code)]
struct Point {x: i32,y: i32,z: i32,
}fn main() {let origin = Point { x: 0, y: 0, z: 0 };match origin {//..表示忽略其他字段Point { x, .. } => println!("x is {}", x),}let numbers = (2, 4, 8, 16, 32);match numbers {//只需要第一个和最后一个值,其他的忽略(first, .., last) => {println!("Some numbers: {}, {}", first, last);}}
}
注意:使用 … 必须是无歧义的。如果期望匹配和忽略的值是不明确的,Rust 会报错。
如下示例展示了一个带有歧义的 … 例子,因此其不能编译:
fn main() {let numbers = (2, 4, 8, 16, 32);match numbers {(.., second, ..) => { println!("Some numbers: {}", second) }}
}
Rust 不可能决定在元组中匹配 second 值之前应该忽略多少个值,以及在之后忽略多少个值。
这段代码可能表明我们意在忽略 2,绑定 second 为 4,接着忽略 8、16 和 32;抑或是意在忽略 2 和 4,绑定 second 为 8,接着忽略 16 和 32,以此类推。
变量名 second 对于 Rust 来说并没有任何特殊意义,所以会得到编译错误,因为在这两个地方使用 … 是有歧义的。
… 在同一个匹配中只能使用一次
4.1.2 使用 _ 忽略整个值
我们已经使用过下划线(_)作为匹配但不绑定任何值的通配符模式了。
虽然 _ 模式作为 match 表达式最后的分支特别有用,也可以将其用于任意模式,包括函数参数中,
//定义一个函数,参数使用下划线来忽略
fn foo(_: i32, y: i32) {println!("This code only uses the y parameter: {}", y);
}fn main() {//调用函数的时候,第一个参数随便写,也可以使用下划线foo(3, 4);
}
大部分情况当你不再需要特定函数参数时,最好修改签名不再包含无用的参数。
在一些情况下忽略函数参数会变得特别有用,比如实现 trait 时,当你需要特定类型签名但是函数实现并不需要某个参数时。
此时编译器就不会警告说存在未使用的函数参数,就跟使用命名参数一样。
如下:
使用嵌套的 _ 忽略部分值
也可以在一个模式内部使用 _ 忽略部分值,例如,当只需要测试部分值但在期望运行的代码中没有用到其他部分时。
如下示例展示了负责管理设置值的代码。业务需求是用户不允许覆盖现有的自定义设置,但是可以取消设置,也可以在当前未设置时为其提供设置。
fn main() {let mut setting_value = Some(5);let new_setting_value = Some(10);match (setting_value, new_setting_value) {//使用Some(_),Some(_)来匹配Some(5)和Some(10)(Some(_), Some(_)) => {println!("Can't overwrite an existing customized value");}_ => {setting_value = new_setting_value;}}println!("setting is {:?}", setting_value);
}
这段代码会打印出 Can’t overwrite an existing customized value 接着是 setting is Some(5)。
在第一个匹配分支,我们不需要匹配或使用任一个 Some 成员中的值;重要的部分是需要测试 setting_value 和 new_setting_value 都为 Some 成员的情况。
在这种情况,我们打印出为何不改变 setting_value,并且不会改变它。
对于所有其他情况(setting_value 或 new_setting_value 任一为 None),这由第二个分支的 _ 模式体现,这时确实希望允许 new_setting_value 变为 setting_value。
通过在名字前以一个下划线开头来忽略未使用的变量
如果你创建了一个变量却不在任何地方使用它, Rust 通常会给你一个警告,因为这可能会是个 bug。
但是有时创建一个还未使用的变量是有用的,比如你正在设计原型或刚刚开始一个项目。
这时你希望告诉 Rust 不要警告未使用的变量,为此可以用下划线作为变量名的开头。
fn main() {let _x = 5;let y = 10;
}
这里得到了警告说未使用变量 y,不过没有警告说未使用下划线开头的变量。
注意, 只使用 _ 和使用以下划线开头的名称有些微妙的不同:比如 _x 仍会将值绑定到变量,而 _ 则完全不会绑定。
fn main() {let s = Some(String::from("Hello!"));if let Some(_s) = s {println!("found a string");}println!("{:?}", s); //报错,因为s的所有权已经转移给_s了
}
使用单独的下划线,变量不会绑定
4.2 匹配守卫与绑定
结合匹配守卫和绑定可以实现复杂的条件判断:
fn main() {let robot_name = Some(String::from("Bors"));match robot_name {//使用ref来获取Some的值的引用//避免了所有权的转移Some(ref name) if name == "Bors" => {println!("Found robot: {}", name);}Some(name) => {println!("Not the robot: {}", name);}None => {}}
}
五、总结
Rust的模式匹配系统是其最强大和最独特的特性之一。它提供了:
-
清晰、表达力强的语法
-
编译时的安全性检查
-
高效的运行时性能
-
对复杂数据结构的强大解构能力
通过掌握模式匹配,大家可以编写出更安全、更清晰、更易于维护的Rust代码。从简单的值匹配到复杂的解构和守卫,模式匹配几乎可以处理任何数据验证和提取需求。
Rust的模式匹配不仅仅是一个语言特性,它体现了Rust的核心哲学:在编译时捕获尽可能多的错误,同时保持运行时的效率。随着你对Rust的深入使用,你会发现模式匹配成为了你工具箱中不可或缺的一部分。
相关文章:

【Rust模式与匹配】Rust模式与匹配深入探索与应用实战
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
React从基础入门到高级实战:React 高级主题 - React Concurrent 特性:深入探索与实践指南
React Concurrent 特性:深入探索与实践指南 引言 随着Web应用对用户体验的要求日益提高,React在2025年的技术环境中引入了并发渲染(Concurrent Rendering)这一革命性特性,旨在提升应用的响应速度和交互流畅度。并发渲…...

electron安装报错处理
electron安装报错 解决方法: 修改 C:\Users\用户名.npmrc下配置文件 添加代码 electron_mirrorhttps://cdn.npmmirror.com/binaries/electron/ electron_builder_binaries_mirrorhttps://npmmirror.com/mirrors/electron-builder-binaries/最后代码 registryhtt…...

NHANES指标推荐:CQI
文章题目:The impact of carbohydrate quality index on menopausal symptoms and quality of life in postmenopausal women 中文标题:碳水化合物质量指数对绝经后妇女更年期症状和生活质量的影响 发表杂志:BMC Womens Health 影响因子&…...
【OpenHarmony】【交叉编译】使用gn在Linux编译3568a上运行的可执行程序
linux下编译arm64可执行程序 一.gn ninja安装二.交叉编译工具链安装1.arm交叉编译工具2.安装arm64编译器 三. gn文件添加arm及arm64工具链四.编译验证 本文以gn nijia安装中demo为例,将其编译为在arm64(rk_3568_a开发板)环境下可运行的程序 一.gn ninja安装 安装g…...
Med-R1论文阅读理解-1
论文总结:Med-R1: Reinforcement Learning for Generalizable Medical Reasoning in Vision-Language Models 论文写了什么? 本文提出了一种名为 Med-R1 的新框架,旨在通过强化学习(Reinforcement Learning, RL)提升…...

【从零开始学习QT】快捷键、帮助文档、Qt窗口坐标体系
目录 Qt Creator 中的快捷键 使用帮助文档 Qt 窗口坐标体系 QT专栏:QT_uyeonashi的博客-CSDN博客 Qt Creator 中的快捷键 • 注释:ctrl / • 运行:ctrl R • 编译:ctrl B • 字体缩放:ctrl 鼠标滑轮 • 查找&am…...
强化学习笔记总结(结合论文)
本篇博客参考来自大佬的开源书籍,结合自己的思考,写了这一篇总结,帮助大家学习了解强化学习的基础知识 文章目录 强化学习特点定义 强化学习应用实例强化学习和监督式学习、非监督式学习分类强化学习和监督式学习的区别:强化学习…...
Java线程安全解决方案全面指南
Java线程安全解决方案全面指南 引言 在多线程编程中,线程安全是保证程序正确性的关键要素。Java作为一门广泛用于并发编程的语言,提供了丰富的线程安全解决方案。本文将全面介绍Java中实现线程安全的各类方法,帮助开发者编写出更健壮的多线…...
superior哥深度学习系列(大纲)
🚀 superior哥深度学习系列学习大纲(2025版) 嘿!各位AI探索者们!👋 这是superior哥精心打造的深度学习学习路线图。从零基础小白到AI实战高手,这份大纲会陪你一路成长!记住ÿ…...

基于stm32的多旋翼无人机(Multi-rotor UAV based on stm32)
由于一直在调试本项目,好久没有发文章,最近本项目的PID调试初见成效!开始正文前首先感谢各位粉丝的支持,以及对本项目技术上支持的老师以及师兄,谢谢你们! 对应源码及文件:源码及文件下载 基于…...

实验分享|基于sCMOS相机科学成像技术的耐高温航空涂层材料损伤检测实验
1实验背景 航空发动机外壳的耐高温涂层材料在长期高温、高压工况下易产生微小损伤与裂纹,可能导致严重安全隐患。传统光学检测手段受限于分辨率与灵敏度,难以捕捉微米级缺陷,且检测效率低下。 某高校航空材料实验室,采用科学相机…...

RAG混合检索:倒数秩融合RRF算法
文章目录 检索增强生成 (RAG)倒数秩融合在 RAG 中的工作原理RRF 背后的数学直觉检索增强生成 (RAG) RAG 是自然语言处理中的一种强大技术,结合了基于检索的模型和生成模型的优势。 如果检索器未能从检索器中获取相关文档,则精度较低,幻觉的可能性会增加。 有些查询适合…...

2011肠衣问题
1 D类竞赛题目---具体题目 D题 天然肠衣搭配问题 天然肠衣(以下简称肠衣)制作加工是我国的一个传统产业,出口量占世界首位。肠衣经过清洗整理后被分割成长度不等的小段(原料),进入组装工序。 传统的生产…...

RG3000网关构建5G LAN智慧工厂智能制造
在工业4.0与智能制造的趋势下,传统制造业正前后往智慧工厂转型升级。在转型过程中,高效、稳定、灵活的网络通信是实现设备互联互通、数据实时交互与智能决策的基础。智联物联RG3000网关,凭借其融合5G通信技术、WiFi6无线传输、边缘计算能力与…...
Rust语言学习教程、案例与项目实战指引
Rust语言学习教程、案例与项目实战指引 一、入门教程 (一)官方核心文档 Rust官方网站的核心文档是踏上Rust学习征程的绝佳起点。这里犹如一座知识宝库,涵盖了Rust编程时可能遇到的几乎所有内容,从基础语法到高级特性,一…...
通信应用高速模数转换器ADC
在5G通信、医疗成像、航空航天及工业自动化等关键领域,高速ADC模数转换器作为信号链的“心脏”,其性能直接决定了系统的精度与效率。然而,如何精确测试高速ADC的动态参数、优化设计验证流程、应对复杂应用场景的挑战,始终是工程师…...
大模型测评选型指南:企业级大模型测评实战解析
在当今数字化飞速发展的时代,AIGC大模型如雨后春笋般涌现,为各行业带来创新变革的同时,其安全性也成为了不容忽视的关键问题。随着人工智能技术加速落地,AIGC大模型的安全合规已成为产业发展的核心命题。那么,企业该如…...
微信小程序学习目录
个人简介 👨💻个人主页: 魔术师 📖学习方向: 主攻前端方向,正逐渐往全栈发展 🚴个人状态: 研发工程师,现效力于政务服务网事业 🇨🇳人生格言&…...
AG32 DMAC实现内部MCU与FPGA通信【知识库】
一、简介 DMAC是独立于MCU和FPGA之外的外设,连接到AHB总线,可通过寄存器配置实现直接内存存取。通过AHB总线实现MCU与FPGA进行高性能通信。理论最高传输速率可达 bus_clock * 32 168MHz * 32 5376Mbps 5.25Gbps,超频到336MHz的形况下&…...

webrtc初了解
1. webrtc的简介 一、WebRTC 是什么? Web Real-Time Communication(网页实时通信),是浏览器原生支持的实时音视频通信技术,无需安装插件或客户端,可直接在浏览器之间实现点对点(P2P)…...

[STM32学习笔记(九)]CubeMX项目使用系统定时器SysTick的中断服务函数进行定时
有很多文章说明了由于HAL_Delay()函数的本质是系统定时器计数,通过全局变量uwTick的不断增加实现的比较延迟。调用HAL_Delay()函数会阻塞其他工作,因此在外设ISR进程调用该延迟时,要特别小心。 因此,现在考虑,既然系统…...
5G 核心网 NGAP UE-TNL 偶联和绑定
引言: 在 5G 核心网架构中,NG 接口作为连接无线接入网(RAN)与核心网(5GC)的关键纽带,承载着大量控制面信令交互。NG 应用协议(NGAP)作为 NG 接口上的核心协议,负责管理 RAN 与 5GC 之间的通信,其中 UE - TNL(User Equipment - Transport Network Layer)偶联和绑定…...
性能测试怎么做?方法、流程与核心要点解析
目录 一、性能测试核心方法论 性能测试五大类型解析 七项关键性能指标 二、性能测试实施流程 需求分析阶段 测试设计阶段 环境搭建要点 测试执行策略 三、性能问题定位与优化 常见瓶颈识别 优化实战案例 四、测试报告编写规范 核心内容框架 数据可视化建议 五、企…...

将ipynb文件转换为markdown格式文件
文章目录 将ipynb文件转换为markdown格式文件nbconvert 包安装nbconvert 使用 将ipynb文件转换为markdown格式文件 有时候,我们需要把Jupyter notebook的.ipynb格式文件转换为markdown格式.md,便于使用。 那么,我们可以通过安装nbconvert包&a…...

Vulnhub_Zico2_wp
一、信息收集 1、主机发现 arp-scan -l 2、端口扫描 nmap -sS -sV 192.168.66.144 nmap -p- -Pn -sC -sV -n 192.168.66.144 whatweb -v 192.168.66.144 这里开放了3个端口,先80端口拿去目录,然后测试下22端口有没有什么未授权之类的,然后…...

【玩转腾讯混元大模型】腾讯混元大模型AIGC系列产品深度体验
【玩转腾讯混元大模型】腾讯混元大模型AIGC系列产品深度体验 腾讯推出的系列AI产品:混元大模型、大模型图像创作引擎、大模型视频创作引擎、腾讯元宝,共同构成了一个强大的AI生态系统;凭借腾讯自研的大规模预训练技术和先进的自然语言处理、计…...
品优购项目(HTML\CSS)
项目效果可访问 http://zhousunyu.3vdo.club 查看 主页 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><titl…...

Attention Is All You Need论文阅读笔记
Attention is All You Need是如今机器学习研究者必读的论文,该文章提出的Transformer架构是如今很多机器学习项目的基础,说该文章极大推动了机器学习领域的研究也不为过。 但这么重要,也是必读的文章对初学者来说其实并不友好,很多…...
深入理解设计模式之中介者模式
深入理解设计模式之:中介者模式(Mediator Pattern) 一、什么是中介者模式? 中介者模式(Mediator Pattern)是一种行为型设计模式。它通过引入一个中介对象,来封装一组对象之间的交互࿰…...