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

Rust语法: 枚举,泛型,trait

这是我学习Rust的笔记,本文适合于有一定高级语言基础的开发者看不适合刚入门编程的人,对于一些概念像枚举,泛型等,不会再做解释,只写在Rust中怎么用。

文章目录

    • 枚举
      • 枚举的定义与赋值
      • 枚举绑定方法和函数
      • match匹配枚举
      • if let语句
      • Option
      • match pattern
        • 基本pattern
        • pattern守卫
    • 泛型
      • 泛型函数
      • 泛型结构体
      • 泛型枚举
      • 为结构体绑定泛型方法
    • trait
      • trait的定义与实现
      • 用trait指定定特定方法
      • impl中的trait约束

枚举

枚举的定义与赋值

枚举的定义格式如下:
enum 枚举名{
值1(附加类型),
值2(附加类型),…
}
其中,关联类型可以省去

例如要创建一个神经网络类型的枚举,就可以这样定义

enum NeuralNetwork {CNN,RNN,GAN,Transformer,GNN
}

下面是传参和创建的例子,其中引用的部分可以看后面的,所有权&生命周期这一部分。

enum NeuralNetwork {CNN,RNN,GAN,Transformer,GNN
}fn main(){let nn1 = NeuralNetwork::CNN; //创建一个NeuralNetwork类型的枚举,值为CNNlet nn2 = NeuralNetwork::Transformer;let nn3 = nn1;printnn(&nn3); //给函数传参printnn(&nn2);
}fn printnn(network: &NeuralNetwork){} //实参表明了需要一个NeuralNetwork类型的引用()

除此之外,枚举可以增加附类型

enum NeuralNetwork { // 所有的网络类型都带有一个附加类型,String表示具体的网络名CNN(String),RNN(String),GAN(String),Transformer(String),GNN(String)
}
enum Test{ // 所有的网络类型都带有一个附加类型,String表示具体的网络名e1,e2(String), e3{x: u32, y: f64}, //绑定了一个匿名结构体类型e4(u32, u32, u32) //绑定一个Tuple
}fn main(){let nn1 = NeuralNetwork::CNN(String::from("TextCNN")); let nn2 = NeuralNetwork::Transformer(String::from("Transformer-XL"));}

枚举绑定方法和函数

与结构体类型,对于枚举,Rust也允许使用impl关键字来绑定方法和函数

enum NeuralNetwork {CNN(String),RNN(String),GAN(String),Transformer(String),GNN(String)
}impl NeuralNetwork {fn make_cnn(s: String) -> NeuralNetwork{ //绑定一个函数,用于创建CNN类型枚举NeuralNetwork::CNN(s)}
}fn main(){let nn1 = NeuralNetwork::make_cnn(String::from("TextCNN"));let nn2 = NeuralNetwork::Transformer(String::from("Transformer-XL"));}

match匹配枚举

match的语法大致如下

match 变量{
结果1 => 表达式1,
结果2 => 表达式2,
_ => 剩余结果处理
}

enum NeuralNetwork {CNN(String),RNN(String),GAN(String)
}fn main(){let nn1 = NeuralNetwork::CNN(String::from("TextCNN"));match nn1 {NeuralNetwork::CNN(s) => println!("CNN 变体为 {}", s), //匹配到对应类型,后面写表达式,而括号内的s就是枚举所绑定类型NeuralNetwork::RNN(s) => println!("RNN 变体为 {}", s),NeuralNetwork::GAN(s) => println!("GAN 变体为 {}", s)}
}

需要注意的是match需要把每一种结果都列出来,如果剩下的不想列可以使用通配符_来表示.

enum NeuralNetwork {CNN(String),RNN(String),GAN(String)
}fn main(){let nn1 = NeuralNetwork::CNN(String::from("TextCNN"));match nn1 {NeuralNetwork::CNN(s) => println!("CNN 变体为 {}", s),_ => println!("非CNN") //剩余类型统一处理}
}

如果箭头后面需要处理更复杂的逻辑,则可以用函数块来写,如下

enum NeuralNetwork {CNN(String),RNN(String),GAN(String)
}fn main(){let nn1 = NeuralNetwork::CNN(String::from("TextCNN"));match nn1 {NeuralNetwork::CNN(s) => {let len = s.len();println!("CNN 变体为 {} {}", s, len);},_ => println!("非CNN");}
}

除此之外match其实是有返回值的,正如函数块的最后一个运算式为返回值一样,match的返回值为=>后的值

enum NeuralNetwork {CNN(String),RNN(String),GAN(String)
}fn main(){let nn1 = NeuralNetwork::CNN(String::from("TextCNN"));let res = match nn1 {NeuralNetwork::CNN(s) => {println!("CNN 变体为 {}", s);s //s是返回值,返回给res,下面同理},NeuralNetwork::RNN(s) => {println!("RNN 变体为 {}", s);s},NeuralNetwork::GAN(s) => {println!("GAN 变体为 {}", s);s}};println!("res is {}", res)
}

除了枚举之外,match也可以匹配别的值

fn main(){let x = 10;match x {1 => println!("Is one!"),2 => println!("Is tow"),_ => println!("Other number!")};
}
fn main(){let x = "adasdasd";match x {"abc" => println!("Is abc!"),"efg" => println!("Is efg"),_ => println!("Other string!")};
}

if let语句

如果指向match一种情况,则可以使用if let这个语法糖,只针对一种模式进行匹配

enum NeuralNetwork {CNN(String),RNN(String),GAN(String)
}fn main(){let nn1 = NeuralNetwork::CNN(String::from("TextCNN"));if let nn1 = NeuralNetwork::CNN{println!("是CNN");}
}

注意,if let后面的判断是=,而不是==。如果想要处理剩余情况,可以再加一个else

enum NeuralNetwork {CNN(String),RNN(String),GAN(String)
}fn main(){let nn1 = NeuralNetwork::CNN(String::from("TextCNN"));if let nn1 = NeuralNetwork::CNN{println!("是CNN");}else{println!("不是CNN");}
}

Option

Option是一种枚举,包含两种类型,分别是Some和None。Rust设计Option就是为了避免None和其它的值做运算而造成一系列错误而设计的。
Option的定义大致如下:

pub enum Option<T> {None,Some(T),
}

Option可以如下使用

fn main(){let x = Option::Some("hello");let y: Option<&str>= Option::None; //这里属于泛型,需要指定Option的泛型类型let z = x + y; // None无法和y运算,从而保证了安全性
}
fn main(){let _x = Option::Some("hello");let y: Option<&str> = None;match y {Option::None => println!("空的"),Option::Some(t) => println!("非空, 是{}", t)}
}

match pattern

基本pattern

match允许更为复杂的匹配,这称之为匹配的pattern,其中常用的操作如下:

  1. | 用于分割多个可能,Rust会从左到右依次检查是否符合

例如:a | b | c则会 检查a后检查b,再检查是否符合c

  1. ()元组用于实现匹配坐标这类的多个参数数据
  2. 可以用…=b, a…=b这种Range来进行范围的匹配

注意,a…b是左闭右开类型,而加上等号则是左闭右闭

  1. _可以用来匹配剩余未匹配的所有值
fn main(){let x: i32 = 100;match x {1 | 2 | 3 => println!("x位于1到3之间"), //会依次检查x是1,2还是3.只要匹配一个就进入后面的语句4 ..=9 => println!("x位于4到9之间"),10 | 100..=1000 => println!("x为10,或者100-1000之间的数"),_ => println!("x不是所期待的数字")};
}
fn main(){let x: (i32, i32) = (-9, -10);match x {(1, 1) => println!("点(1, 1)"),(1, 2 | 3 | 4) => println!("点(1,2), (1,3)或((1,4))"),(..=-1, ..=-1) => println!("第三象限的点"),_ => println!("其他区域的点")};
}

可以使用@符号把必要时的某个值绑定到变量上,操作为 变量 @ 匹配式

fn main(){let x: (i32, i32) = (-9, -10);match x {(1, 1) => println!("点(1, 1)"),(1, 2 | 3 | 4) => println!("点(1,2), (1,3)或((1,4))"),(x @ ..=-1, y @ ..=-1) => println!("第三象限的点({}, {})", x, y), //绑定第一个空的值到x,同理绑定y。_ => println!("其他区域的点")};
}

pattern守卫

pattern后面可以加上if判断语句来进一步的判断这个匹配是否合法,示例如下

fn judge_prime(x: i32) -> bool{// TODO: 判断素数true
}
fn main(){let tmp: (i32, i32) = (-9, -10);match tmp {(x @ 0..=10, y @ _) if x == y => println!("在y=x直线上(0 <= x <= 100)"),(x @ 0..=100, y @ 0..=100) if judge_prime(x) && judge_prime(y) => println!("(x, y)为0-100内的素数坐标"),_ => println!("")};
}

当然if后面的语句可以替换成函数块{}只要其返回值是bool类型即可。

fn judge_prime(_x: i32) -> bool{// TODO: 判断素数true
}fn main(){let tmp: (i32, i32) = (-9, -10);match tmp {(x, y) if x == y => println!("在y=x直线上"), //此时x,y无绑定,也就是无绑定上的约束(x @ 0..=100, y @ 0..=100) if {let tmp: bool = judge_prime(x);tmp && judge_prime(y)}=> println!("(x, y)为0-100内的素数坐标"),_ => println!("")};
}

泛型

如其他语言(CPP,JAVA)一样,Rust也支持泛型。

泛型函数

泛型函数需要在函数名上指明泛型类型,通常用T,U这种大写字母来表示

fn qpow<T>(base: T, p: i32) -> T{//TODO实现快速幂的逻辑
}

上述函数中T表示某个抽象的类型,而这个类型需要在函数名部分标注出来。随后的base和返回值都是T类型。
当然涉及到两个或者多个翻新类型时,需要都在函数名后面声明出

fn Test<T, U>(x: T, y: U) -> (T, U){//TODO
}

泛型结构体

与函数类似,可以在结构体明上声明某个或者多个抽象类型

struct Point<T>{x: T,y: T
}
fn main(){let ip = Point{x: 10, y: 10}; //此时ip类型为Point<i32>let fp = Point{x: 10.0, y: 11.1};//此时ip类型为Point<f64>
}

注意,Rust在编译时会把所有的抽象类型T替换成具体的类型,因为Rust是静态的,所以在编译之后所有的抽象类型都已经有具体的确定类型的值了。

struct Point<T>{x: T,y: T
}
fn main(){let ip: Point<i64> = Point{x: 10, y: 10}; //强制约束为i64let fp = Point{x: 10.0, y: 11};//报错,因为有两个类型
}

泛型枚举

枚举的泛型就是把其变体所绑定的类型内添加泛型,前面的Option的Some就是这个原理。

enum Test<T, U> {SOME(T, U),OTHER(T),NO

为结构体绑定泛型方法

为结构体绑定方法使用impl关键字,如果该结构体是一个泛型结构体,则需要再impl后面加表明抽象类型。

struct Point<T>{x: T,y: T    
}impl Point<i32> { //只为i32类型实现判断素数坐标的方法, 由于是实现具体类型所以不需要再impl后面加尖括号fn judge_prime(&self) -> bool{//TODO判断素数}
}impl<T> Point<T> { //为所有类型都实现一个画图的方法,抽象方法要加尖括号表明抽象类型fn show_point(&self) -> (){//TODO画图}
}

注意,此时impl的泛型参数不影响具体方法的参数

struct Point<T, U>{x: T,y: U
}impl<T, U> Point<T, U> {fn make_new_point<W>(&self, other_point: Point<T, W>) -> Point<T, W>{Point { x: self.x.clone(),  //这里会有报错,具体原因看后面的trait部分y: other_point.y }}
}fn main(){
}

trait

trait的定义与实现

trait是Rust的一个类似于接口的类型,他可以为enum,struct来定义一套标准的接口,或者默认的某些方法。

trait 名字{
函数|抽象函数
}

看下面的例子

trait Draw {fn _draw_atom(&self) ->(); //实现单个点的绘画,是一个抽象的方法fn draw(&self) -> (){ //draw绘画调用_draw_atom,是一个已经实现的方法self._draw_atom()}
}

使用

impl trait类型 for 结构体|枚举

来为结构体或者枚举绑定方法

struct Point{x: f64,y: f64
}struct Line{A: f64,B: f64
}trait Draw {fn _draw_atom(&self) ->();fn draw(&self) -> (){ //该方法为所有实现Draw trait的结构体/枚举所共有self._draw_atom()}
}impl Draw for Point { //为Point结构体实现fn _draw_atom(&self) ->() {println!("{} {}", self.x, self.y);}
}impl Draw for Line {//为Line结构体实现fn _draw_atom(&self) -> (){println!("{}x + {}y = 0", self.A, self.B);}
}

用trait指定定特定方法

首先对于简单的约束,我们可以直接在函数参数后面加上 impl trait类型 的方式来要求某个参数必须实现特定的trait

fn Test(x: impl Draw){ //约束x必须实现Draw
}

如果类型比较多,且复杂则可以使用Bound的方式具体做法如下

在函数名后面用尖括号,写上泛型,然后后面用冒号指定trait
函数名<T: trait1 + traiit2+…, U: trait1+traitk…>

use std::fmt::Display; //使用fmt内的Display trait
fn Test<T: Draw + Display, U: Display>(x: T, y: U){} 
//要求x实现了Draw和Display两个trait,而y只要求实现Display这个trait

此时你会发现bound约束太长了,降低了函数的可读性。于是Rust允许使用where关键字把Bound约束后置, 具体做法如下

  1. 在函数尖括号后声明泛型,T,U等变量。
  2. 在函数的函数体前用where关键字,后面跟上每个泛型变量的约束trait
use std::fmt::Display;
fn Test<T, U>(x: T, y: U)
whereT: Draw + Display, //约束TU: Display //约束U
{//TODO:函数体
} 

我们同样可以再返回类型上约束实现具体的trait。但此时需要注意,返回的类型必须要是一种类型,不能使用分支语句使其返回多种可能的类型

use std::fmt::Display;
fn Test<T, U>(x: T, y: U) -> U //返回类型必须实现了Display
whereT: Draw + Display, //约束TU: Display //约束U
{//TODO:函数体
} 

impl中的trait约束

除此之外,在impl中的泛型T,也可以进行相对应的trait的约束

impl<T: Display> Point<T>{ 
//对所有实现了Display trait的类型T,其Point<T>都会具有test方法fn test(&self){}}

trait可以进行覆盖实现,也就是为所有实现某些trait的类型添加一些方法


trait Hello {fn print_hello(){println!("hello");}
}impl<T: std::fmt::Display> Hello for T{//为所有实现了Display这个trait的类型都添加一个print_hello函数}
fn main(){i32::print_hello(); //此时实现了Display的i32类型,也可以调用这个方法了
}

相关文章:

Rust语法: 枚举,泛型,trait

这是我学习Rust的笔记&#xff0c;本文适合于有一定高级语言基础的开发者看不适合刚入门编程的人&#xff0c;对于一些概念像枚举&#xff0c;泛型等&#xff0c;不会再做解释&#xff0c;只写在Rust中怎么用。 文章目录 枚举枚举的定义与赋值枚举绑定方法和函数match匹配枚举…...

hivesql-dayofweek 函数

返回日期或时间戳的星期几。 此函数是 extract(DAYOFWEEK FROM expr) 的同义函数。 语法 dayofweek(expr) 参数 expr&#xff1a;一个 DATE 或 TIMESTAMP 表达式。 返回 一个 INTEGER&#xff0c;其中 1 Sunday 和 7 Saturday。 示例 > SELECT dayofweek(2009-07-30)…...

DIP:《Deep Image Prior》经典文献阅读总结与实现

文章目录 Deep Image Prior1. 方法原理1.1 研究动机1.2 方法 2. 实验验证2.1 去噪2.2 超分辨率2.3 图像修复2.4 消融实验 3. 总结 Deep Image Prior 1. 方法原理 1.1 研究动机 动机 深度神经网络在图像复原和生成领域有非常好的表现一般归功于神经网络学习到了图像的先验信息…...

LAXCUS如何通过技术创新管理数千台服务器

随着互联网技术的不断发展&#xff0c;服务器已经成为企业和个人获取信息、进行计算和存储的重要工具。然而&#xff0c;随着服务器数量的不断增加&#xff0c;传统的服务器管理和运维方式已经无法满足现代企业的需求。LAXCUS做为专注服务器集群的【数存算管】一体化平台&#…...

【Java】BF算法(串模式匹配算法)

☀️ 什么是BF算法 BF算法&#xff0c;即暴力算法&#xff0c;是普通的模式匹配算法&#xff0c;BF算法的思想就是将目标串S的第一个与模式串T的第一个字符串进行匹配&#xff0c;若相等&#xff0c;则继续比较S的第二个字符和T的第二个字符&#xff1b;若不相等&#xff0c;则…...

Vue:使用Promise.all()方法并行执行多个请求

在Vue中&#xff0c;可以使用Promise.all()方法来并行执行多个请求。当需要同时执行多个异步请求时&#xff0c;可以将这些请求封装为Promise对象并使用Promise.all()方法来执行它们。 示例1&#xff1a; 以下是一个示例代码&#xff0c;展示了如何通过Promise.all()方法并行…...

21.0 CSS 介绍

1. CSS层叠样式表 1.1 CSS简介 CSS(层叠样式表): 是一种用于描述网页上元素外观和布局的样式标记语言. 它可以与HTML结合使用, 通过为HTML元素添加样式来改变其外观. CSS使用选择器来选择需要应用样式的元素, 并使用属性-值对来定义这些样式.1.2 CSS版本 CSS有多个版本, 每个…...

下一代计算:嵌入AI的云/雾/边缘/量子计算

计算系统在过去几十年中推动了计算机科学的发展&#xff0c;现在已成为企业世界的核心&#xff0c;提供基于云计算、雾计算、边缘计算、无服务器计算和量子计算的服务。现代计算系统解决了现实世界中许多需要低延迟和低响应时间的问题。这有助于全球各地的青年才俊创办初创企业…...

Gitlab-第四天-CD到k8s集群的坑

一、.gitlab-ci.yml #CD到k8s集群的 stages: - deploy-test build-image-deploy-test: stage: deploy-test image: bitnami/kubectl:latest # 使用一个包含 kubectl 工具的镜像 tags: - k8s script: - ls -al - kubectl apply -f deployment.yaml # 根据实际情况替换…...

【Java基础】Java对象的生命周期

【Java基础】Java对象的生命周期 一、概述 一个类通过编译器将一个Java文件编译为Class字节码文件&#xff0c;然后通过JVM中的解释器编译成不同操作系统的机器码。虽然操作系统不同&#xff0c;但是基于解释器的虚拟机是相同的。java类的生命周期就是指一个class文件加载到类…...

【每日一题】88. 合并两个有序数组

【每日一题】88. 合并两个有序数组 88. 合并两个有序数组题目描述解题思路 88. 合并两个有序数组 题目描述 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 …...

Navicat Premium连接sqlserve数据库失败?你需要注意这几点看看配置对了么?

新建数据库连接的时候这么填的信息 报错 原因1&#xff1a;sqlserver数据库的端口和IP地址之间不是&#xff1a;连接而是用&#xff0c;连接 改成如下样式用逗号连接端口和IP地址就好了 原因2&#xff1a;在Navicat Premium中需要安装一个sqlserver的插件 找到安装路径的根目…...

207、仿真-51单片机脉搏心率与血氧报警Proteus仿真设计(程序+Proteus仿真+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 四、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选择 方案一&a…...

flutter 初识(开发体验,优缺点)

前言 最近有个跨平台桌面应用的需求&#xff0c;需要支持 windows/linux/mac 系统&#xff0c;要做个更新应用的小界面&#xff0c;主要功能就是下载更新文件并在本地进行替换&#xff0c;很简单的小功能。 花了几分钟构建没做 UI 优化的示例界面&#xff1a; 由于我们的客…...

校验vue prop的几种方式

校验vue prop的几种方式 vue 要求将传递给组件的任何数据显式声明为 props。此外&#xff0c;它还提供了强大的内置机制来验证该数据。这充当组件和父级组件之间的约定&#xff0c;并确保组件能按预期使用。 让我们看看怎么对props进行校验。它可以帮助我们在开发和调试过程中…...

vue+springboot 前后端分离 上传文件处理后再下载,并且传递参数

vue代码 <template><div><input type"file" ref"fileInput" accept".json"/><el-button click"upload">上传</el-button></div> </template><script> export default {name: "…...

【Linux操作系统】举例解释Linux系统编程中文件io常用的函数

在Linux系统编程中&#xff0c;文件IO操作是非常常见和重要的操作之一。通过文件IO操作&#xff0c;我们可以打开、读取、写入和关闭文件&#xff0c;对文件进行定位、复制、删除和重命名等操作。本篇博客将介绍一些常用的文件IO操作函数。 文章目录 1. open()1.1 原型、参数及…...

Ubuntu和centos版本有哪些区别

Ubuntu和CentOS是两个非常流行的Linux发行版&#xff0c;它们在一些方面有一些区别&#xff0c;如下所示&#xff1a; CentOS的版本发布周期相对较长&#xff0c;主要是因为它是基于RedHatEnterpriseLinux(RHEL)的。这意味着在RHEL发布后才能推出对应的CentOS版本。而Ubuntu则在…...

Netty:ChannelHandler抛出异常,对应的channel被关闭

说明 使用Netty框架构建的socket服务端在处理客户端请求时&#xff0c;每接到一个客户端的连接请求&#xff0c;服务端会分配一个channel处理跟该客户端的交互。如果处理该channel数据的ChannelHandler抛出异常没有捕获&#xff0c;那么该channel会关闭。但服务端和其它客户端…...

pytest结合 allure 打标记之的详细使用

前言 前面我们提到使用allure 可以生成漂亮的测试报告&#xff0c;下面就Allure 标记我们做详细介绍。 allure 标记 包含&#xff1a;epic&#xff0c;feature, story, title, testcase, issue, description, step, serverity, link, attachment 常用的标记 allure.feature…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...