【Rust】结构体
目录
- 结构体
- 结构体的定义和实例化
- 结构体使用场景
- 方法
- 定义方法
- 多参数方法
- 关联函数
- 多个 impl 块
结构体
结构体,是一个自定义数据类型,允许包装和命名多个相关的值,从而形成一个有意义的组合,类似于 C语言中的结构体或者 Java 中的类。
结构体的定义和实例化
结构体和元组类似,它们都包含多个相关的值。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。
定义结构体,需要使用 struct
关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,称为字段。例如,以下是一个存储用户账号信息的结构体:
struct User {active: bool,username: String,email: String,sign_in_count: u64,
}
一旦定义了结构体后,为了使用它,通过为每个字段指定具体值来创建这个结构体的实例。创建一个实例需要以结构体的名字开头,接着在大括号中使用 key: value
键 - 值对的形式提供字段,其中 key 是字段的名字,value 是需要存储在字段中的数据值。实例中字段的顺序不需要和它们在结构体中声明的顺序一致。换句话说,结构体的定义就像一个类型的通用模板,而实例则会在这个模板中放入特定数据来创建这个类型的值。
fn main() {let user1 = User {active: true,username: String::from("someusername123"),email: String::from("someone@example.com"),sign_in_count: 1,};
}
为了从结构体中获取某个特定的值,可以使用点号。举个例子,想要用户的邮箱地址,可以用 user1.email
。如果结构体的实例是可变的,可以使用点号并为对应的字段赋值。
fn main() {let mut user1 = User {active: true,username: String::from("someusername123"),email: String::from("someone@example.com"),sign_in_count: 1,};user1.email = String::from("anotheremail@example.com");
}
注意整个实例必须是可变的;Rust 并不允许只将某个字段标记为可变。另外需要注意同其他任何表达式一样,可以在函数体的最后一个表达式中构造一个结构体的新实例,来隐式地返回这个实例。
struct User {active: bool,username: String,email: String,sign_in_count: u64,
}fn build_user(email: String, username: String) -> User {User {active: true,username: username,email: email,sign_in_count: 1,}
}fn main() {let user1 = build_user(String::from("someone@example.com"),String::from("someusername123"),);
}
可以使用字段初始化简写语法来重写 build_user
,这样其行为与之前完全相同,不过无需重复 username
和 email
了。
fn build_user(email: String, username: String) -> User {User {active: true,username,email,sign_in_count: 1,}
}
在软件开发中,经常会遇到这样一个需求:基于一个已有对象,创建一个稍有不同的新对象。这在 Java 中操作略显繁琐:
public class User {public String name;public int age;public User(String name, int age) {this.name = name;this.age = age;}public static void main(String[] args) {User user1 = new User("Alice", 20);User user2 = new User(user1.name, 25); // 手动复制 name}
}
问题:字段一多,复制变麻烦;易出错,忘了某个字段;每个类都需要手动写“复制逻辑”。
像这种使用旧实例的大部分值但改变其部分值来创建一个新的结构体实例通常是很有用的。在 Rust 中这可以通过结构体更新语法实现。
struct User {active: bool,username: String,email: String,sign_in_count: u64,
}fn main() {let user1 = User {email: String::from("someone@example.com"),username: String::from("someusername123"),active: true,sign_in_count: 1,};let user2 = User {active: user1.active,username: user1.username,email: String::from("another@example.com"),sign_in_count: user1.sign_in_count,};
}
这个时候就会有人要问了“主播主播,你这个代码不是跟 Java 中的差不多吗?不也是手动将每个字段“复制”进去吗?”,Rust 中可以使用 ..
语法来解决手动“复制”相同字段的问题。
fn main() {let user1 = User {email: String::from("someone@example.com"),username: String::from("someusername123"),active: true,sign_in_count: 1,};let user2 = User {email: String::from("another@example.com"),..user1};
}
当结构体中包含 String
类型字段时,赋值操作会涉及所有权的“移动”或“克隆”。使用结构更新语法或赋值语法时,如果字段是非 Copy
类型,会发生所有权移动。如果 user2 中的字段使用了全新构造的 String
(不是从 user1 移动的),user1 的字段依然有效。对于实现了 Copy
trait 的字段,赋值行为是按值复制,不影响原字段。
也可以定义与元组类似的结构体,称为元组结构体。元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型。当你想给整个元组取一个名字,并使元组成为与其他元组不同的类型时,元组结构体是很有用的,这时像常规结构体那样为每个字段命名就显得多余和形式化了。
要定义元组结构体,以 struct
关键字和结构体名开头并后跟元组中的类型。例如,下面是两个分别叫做 Color
和 Point
元组结构体的定义和用法:
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);fn main() {let black = Color(0, 0, 0);let origin = Point(0, 0, 0);
}
元组结构体实例类似于元组,你可以将它们解构为单独的部分,也可以使用
.
后跟索引来访问单独的值等等。
也可以定义一个没有任何字段的结构体,它们被称为类单元结构体因为它们类似于 ()
,即元组类型一节中提到的 unit 类型。类单元结构体常常在你想要在某个类型上实现 trait 但不需要在类型中存储数据的时候发挥作用。
trait Greet {fn greet();
}struct English;
struct Chinese;impl Greet for English {fn greet() {println!("Hello!");}
}impl Greet for Chinese {fn greet() {println!("你好!");}
}fn main() {English::greet();Chinese::greet();
}
这里 English
和 Chinese
都是类单元结构体,用作行为的区别单位。
结构体使用场景
写一段计算矩形面积的代码示例:
fn main() {let x = 20;let y = 30;println!("The area of the rectangle is {}", area(x, y));
}fn area (width: i32, height: i32) -> i32{width * height
}
问题:width
和 height
是相关联的,但看不出来;调用和传参不够清晰,也就是不够结构化。
使用元组对代码进行改进:
fn main() {let rect = (20,30);println!("The area of the rectangle is {} square pixels.", area(rect));
}fn area (rect: (i32,i32)) -> i32 {rect.0 * rect.1
}
问题:虽然把两个相关值组合在一起增加了一些结构性,但是不能表达含义(rect1.0
和 rect1.1
看不出哪个是宽、哪个是高)。
使用结构体对代码进行改进:
struct Rectangle {width: i32,height: i32,
}fn main() {let rect = Rectangle{ width: 20,height: 30,};println!("The area of the rectangle is {} square pixels.", area(&rect));
}fn area (rect: &Rectangle) -> i32 {rect.width * rect.height
}
这样不仅将相关数据组合成一个有名字、有含义的整体;而且字段具名,可读性强;还可以扩展方法、trait 等行为。
与元组、数组一样,用 {}
是无法输出整个结构体的,需要实现 Debug
trait 并使用 {:?}
或 {:#?}
才能输出:
#[derive(Debug)] //实现 Debug trait
struct Rectangle {width: i32,height: i32,
}fn main() {let rect = Rectangle{width: 20,height: 30,};println!("使用':?'的输出结果为:{:?}", rect);println!("使用':#?'的输出结果为:{:#?}", rect);
}
输出结果如下:
使用':?'的输出结果为:Rectangle { width: 20, height: 30 }
使用':#?'的输出结果为:Rectangle {width: 20,height: 30,
}
当多个数据具有关联关系且想传递/处理它们时,使用结构体;结构体比元组更具可读性和可扩展性;
Debug
trait 可以方便调试输出结构体。
方法
方法与函数类似:它们使用 fn
关键字和名称声明,可以拥有参数和返回值,同时包含在某处调用该方法时会执行的代码。不过方法与函数是不同的,因为它们在结构体(或者是枚举或 trait 对象)的上下文中被定义,并且它们第一个参数总是 self
,它代表调用该方法的结构体实例。
定义方法
下面是一个定义方法的代码示例:
struct Rectangle {width: i32,height: i32,
}impl Rectangle {fn area(&self) -> i32 {self.width * self.height}
}
fn main() {let rect = Rectangle{width: 20,height: 30,};println!("The area of the rectangle is {} square pixels.", rect.area());
}
为了使函数定义于 Rectangle
的上下文中,使用了一个 impl
块(impl
是 implementation的缩写),这个 impl
块中的所有内容都将与 Rectangle
类型相关联。接着将 area
函数移动到 impl
大括号中,并将签名中的第一个(在这里也是唯一一个)参数和函数体中其他地方的对应参数改成 self
。
在 area
的签名中,使用 &self
来替代 rectangle: &Rectangle
,&self
实际上是 self: &Self
的缩写。在一个 impl
块中,Self
类型是 impl
块的类型的别名。方法的第一个参数必须有一个名为 self
的Self
类型的参数,所以 Rust 让你在第一个参数位置上只用 self
这个名字来简化。注意,这里仍然需要在 self
前面使用 &
来表示这个方法借用了 Self
实例,就像我们在 rectangle: &Rectangle
中做的那样。方法可以选择获得 self
的所有权,或者像这里一样不可变地借用 self
,或者可变地借用 self
,就跟其他参数一样。
这里选择 &self
的理由跟在函数版本中使用 &Rectangle
是相同的:并不想获取所有权,只希望能够读取结构体中的数据,而不是写入。如果想要在方法中改变调用方法的实例,需要将第一个参数改为 &mut self
。通过仅仅使用 self
作为第一个参数来使方法获取实例的所有权是很少见的;这种技术通常用在当方法将 self
转换成别的实例的时候,这时我们想要防止调用者在转换之后使用原始的实例。
以下通过 Java 中的 this
来类比 self
:
写法 | 所有权情况 | 类比 Java | 使用场景 |
---|---|---|---|
self | 传入“实例的所有权”(值本身) | Java 中没有类似的东西(Rust 专属的所有权转移) | 当你要“消耗”这个对象或转移它 |
&self | 传入“实例的不可变引用”(你不能修改字段) | this (不可变) | 常用于读取字段、不修改对象 |
&mut self | 传入“实例的可变引用”(你可以修改字段) | this (可变,Java 默认就是) | 需要修改字段、更新对象 |
调用方法使用点语法 .
来实现,相当于 Java 中对象调用成员方法,rect.area()
。
在 C/C++ 语言中,有两个不同的运算符来调用方法:.
直接在对象上调用方法,而 ->
在一个对象的指针上调用方法,这时需要先解引用(dereference)指针。换句话说,如果 object
是一个指针,那么 object->something()
就像 (*object).something()
一样。
Rust 并没有一个与 ->
等效的运算符;相反,Rust 有一个叫 自动引用和解引用(automatic referencing and dereferencing)的功能。方法调用是 Rust 中少数几个拥有这种行为的地方。
它是这样工作的:当使用 object.something()
调用方法时,Rust 会自动为 object
添加 &
、&mut
或 *
以便使 object
与方法签名匹配。也就是说,这些代码是等价的:
p1.distance(&p2);
(&p1).distance(&p2);
多参数方法
方法的参数也可以有多个,比如下面这个例子:比较第一个长方形能否完全包含第二个长方形:
#[derive(Debug)]
struct Rectangle {width: i32,height: i32,
}
impl Rectangle {fn can_hold(&self, other: &Rectangle) -> bool{self.width > other.width && self.height > other.height}
}
fn main() {let rect1 = Rectangle {width: 30,height: 50,};let rect2 = Rectangle {width: 10,height: 40,};let rect3 = Rectangle {width: 60,height: 45,};println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3))
}
定义一个方法位于 impl Rectangle
块中,方法名是 can_hold
,并且它会获取另一个 Rectangle
的不可变借用作为参数。通过观察调用方法的代码可以看出参数是什么类型的:rect1.can_hold(&rect2)
传入了 &rect2
,它是一个 Rectangle
的实例 rect2
的不可变借用。这是可以理解的,因为只需要读取 rect2
(而不是写入,这意味着需要一个不可变借用),而且希望 main
保持 rect2
的所有权,这样就可以在调用这个方法后继续使用它。can_hold
的返回值是一个布尔值,其实现会分别检查 self
的宽高是否都大于另一个 Rectangle
。
关联函数
把 impl
块中定义的、不把 self
作为第一个参数的函数叫做关联函数(不是方法)。例如前面创建 String 类型变量使用的 String::from()
就是个关联函数。关联函数类似于 Java 中的静态方法,通过结构体名直接调用。关联函数常用于构造器。以下是一个例子:
#[derive(Debug)]
struct Rectangle {width: i32,height: i32,
}impl Rectangle {//构造器——正方形fn square(size: i32) -> Self {Self {width: size,height: size,}}//构造器——长方形fn rectangle(width: i32, height: i32) -> Self {Self {width,height,}}
}
fn main() {let square = Rectangle::square(3);println!("{:?}", square);let rectangle = Rectangle::rectangle(3, 4);println!("{:?}", rectangle);
}
输出结果如下:
Rectangle { width: 3, height: 3 }
Rectangle { width: 3, height: 4 }
关键字 Self
在函数的返回类型中代指在 impl
关键字后出现的类型,在这里是 Rectangle
使用结构体名和 ::
语法来调用这个关联函数:比如 let sq = Rectangle::square(3);
。这个函数位于结构体的命名空间中:::
语法用于关联函数和模块创建的命名空间。
同样在 Rust 中也有类似于 Java 类中的 getter/setter 方法:
#[derive(Debug)]
struct Rectangle {width: i32,height: i32,
}impl Rectangle {//构造器fn square(size: i32) -> Self {Self {width: size,height: size,}}//setter方法fn square_width_set(&mut self, size: i32){self.width = size;self.height = size;}//getter方法fn square_width_get(&self) -> i32{self.width}
}
fn main() {let mut rect = Rectangle::square(3);println!("{:?}", rect);println!("{:?}", rect.square_width_get());rect.square_width_set(5);println!("{:?}", rect);println!("{:?}", rect.square_width_get());
}
输出结果如下:
Rectangle { width: 3, height: 3 }
3
Rectangle { width: 5, height: 5 }
5
多个 impl 块
每个结构体都允许拥有多个 impl
块。例如:
impl Rectangle {fn area(&self) -> u32 {self.width * self.height}
}impl Rectangle {fn can_hold(&self, other: &Rectangle) -> bool {self.width > other.width && self.height > other.height}
}
不过这里没有理由将这些方法分散在多个 impl
块中,不过这是有效的语法。后面讨论泛型和 trait 时会看到实用的多 impl
块的用例。
相关文章:
【Rust】结构体
目录 结构体结构体的定义和实例化结构体使用场景方法定义方法多参数方法关联函数多个 impl 块 结构体 结构体,是一个自定义数据类型,允许包装和命名多个相关的值,从而形成一个有意义的组合,类似于 C语言中的结构体或者 Java 中的…...
青少年编程与数学 02-019 Rust 编程基础 01课题、环境准备
青少年编程与数学 02-019 Rust 编程基础 01课题、环境准备 一、Rust核心特性应用场景开发工具社区与生态 二、Rust 和 Python 比较1. **内存安全与并发编程**2. **性能**3. **零成本抽象**4. **跨平台支持**5. **社区与生态系统**6. **错误处理**7. **安全性**适用场景总结 三、…...
深入理解Embedding Models(嵌入模型):从原理到实战(上)
🐇明明跟你说过:个人主页 🏅个人专栏:《深度探秘:AI界的007》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、嵌入模型是什么 2、在NLP、推荐系统、知识图谱等领域…...
世界耳机品牌与排名
耳机可以说是日常用的比较多的产品之一,而且现在的耳机相较于传统的耳机还多了很多的功能,比如现在经常开车的人实用的蓝牙耳机,虽然日常用的多,那么你知道全球知名的耳机品牌有哪些吗? 拜亚耳机,德国品牌&…...
防静电地板人工费多少钱一平方米?2025年报价解析!
在机房、实验室、数据中心等专业场所,防静电地板是保障设备正常运行的关键“防线”。但很多人在装修时,面对“防静电地板安装人工费”的报价往往一头雾水——有的报25元/㎡,有的却要50元/㎡,差价背后究竟藏着什么门道?…...
【详细图文】使用MobaXterm的SSH功能远程连接服务器,并创建pytorch环境,使用yolov8训练数据集
目录 一、使用MobaXterm连接服务器 1、官网下载MobaXterm 2、SSH连接服务器 二、查看服务器的基本信息 1、查看服务器基本信息(可选) (1)查看主机名和系统版本 (2)查看CPU信息 (3)查看内存信息 (4)查看网卡信息 (5)查看总进程数 (6)查看活动进程数 (…...
路由器断流排查终极指南:从Ping测试到Wireshark抓包5步定位法
测试路由器是否出现“断流”(网络连接间歇性中断),需通过多维度排查硬件、软件及外部干扰因素。以下是详细步骤指南: 一、基础环境准备 设备连接 有线测试:用网线将电脑直接连接路由器LAN口,排除WiFi干扰。…...
小白借助ai对全栈进行浅浅理解(学习笔记)-Lambda、Optional 避免空指针与新的日期时间 API
学习顺序:Java 基础 → Spring Boot → Vue → 前后端整合 → 数据库 → 部署 → 进阶实战。 Lambda 表达式(Lambda 表达式是 Java 8 引入的核心特性,旨在简化函数式编程,替代冗长的匿名内部类,使代码更简洁、灵活 &am…...
可观测性方案怎么选?SelectDB vs Elasticsearch vs ClickHouse
可观测性(Observability)是指通过系统的外部输出数据,推断其内部状态的能力。可观测性平台通过采集、存储、可视化分析三大可观测性数据:日志(Logging)、链路追踪(Tracing)和指标&am…...
100个常用的DeepSeek指令
日常生活类(20个) 1. 新闻解读:请为我解读今天的热点新闻。 2. 天气查询:请查询……的天气并推荐着装。 3. 旅行攻略:请制定前往……的旅行攻略。 4. 菜谱生成:请生成……菜的具体做法。 5. 解决方案&…...
【C语言】--指针超详解(二)
目录 一.const修饰指针 1.1--const修饰变量 1.2--const修饰指针变量 二.野指针 2.1--野指针成因 2.1.1--指针未初始化 2.1.2--指针越界访问 2.1.3-- 指针指向的空间释放 2.2--如何规避野指针 2.2.1--指针初始化 2.2.2--小心指针越界 2.2.3--指针变量不再使用时&am…...
git 多个提交记录合并为一个
1.场景 有时候用devops等平台测试问题,需要多次修改小的记录提交,但是最终我们在合并主干的时候不想留那么多乱七八糟的记录,就需要在此分支合并这些提交记录,再合并到主干。 2.交互式变基 2.1 确定要合并的提交范围 # 查看最近…...
AI视频生成的艺术:镜头语言
前言 AI视频生成技术正逐渐改变我们创作和消费视频内容的方式,各式各样的AI视频制作软件正在不断的涌现,比如可灵、即梦、runway等。虽然AI视频生成的交互方式(自然语言)极大的减少了我们创作视频的门槛,但要让AI正确理解并创造出符合我们期望的视频,我们可能还是需要了解…...
机器学习与深度学习
目录 一、机器学习 (一)机器学习的分类 1. 监督学习 2. 无监督学习 3. 强化学习 (二)机器学习的应用场景 二、深度学习 (一)深度学习的核心原理 (二)常见的深度学习模型 …...
数字孪生市场格局生变:中国2025年规模214亿,工业制造领域占比超40%
一、技术深度解析:数字孪生的核心技术栈与演进 1. 从镜像到自治:数字孪生技术架构跃迁 三维重建突破:LiDAR点云精度达2cm,无人机测深刷新频率5Hz,支撑杭州城市大脑内涝预警模型提前6小时预测。AI算法融合:…...
数字孪生[IOC]常用10个技术栈(总括)
1. 什么是数字孪生? 数字孪生(Digital Twin) 是通过数字化技术对物理实体(如设备、系统或环境)进行高精度建模和实时映射的虚拟副本。其核心是通过 数据驱动 实现物理世界与虚拟世界的双向交互,支持实时监控…...
WPF主窗体子窗体关联方法
步骤: 1、创建WPF项目 2、设计主窗体,选定显示子窗体的区域(MainWindow.xaml) 3、在想要显示子窗体的区域填写如下代码(MainWindow.xaml) 4、创建子窗体 5、建立调用子窗体事件,下图一是load事件,也可以是…...
笔记本电脑实现网线内网 + Wi-Fi外网同时使用的配置方案
1、同时连接两个网络 插入网线连接内网,确保内网IP地址正常获取(如10.143.88.x);连接Wi-Fi接入外网,确认可正常访问互联网(如网关为192.168.8.1)。 2、 记录关键网络参数 内网网关&#…...
探讨关于智能体(Agent)结合 Dify、大语言模型(LLM)以及 Qwen-3 模型的项目或概念
1. Dify 的作用 Dify 是一个开源的 AI 框架,它可以帮助开发者快速搭建和部署 AI 应用。它可以作为一个基础架构,为智能体提供以下支持: 应用开发与部署:Dify 可以帮助开发者快速搭建智能体的前端和后端架构,包括用户界…...
2025 后端自学UNIAPP【项目实战:旅游项目】3、API接口请求封装,封装后的简单测试以及实际使用
一、创建请求封装目录 选中自己的项目,右键鼠标---->新建---->目录---->名字自定义【我的是api】 二、创建两个js封装文件 选中封装的目录,右键鼠标---->新建---->js文件---->名字自定义【我的两个js文件分别是my_http和my_api】 三…...
【electron+vue】常见功能之——调用打开/关闭系统软键盘,解决打包后键盘无法关闭问题
效果图展示 实现思路:通过input标签聚焦失焦的方式,实现系统软键盘的显示隐藏。 使用场景:一体机电脑,无外接键盘。 html <el-input v-model"idNumber" placeholder"请输入" focus"showKeyboard&qu…...
告别手动输入密码:基于SSHPass的自动化文件传输实践告别手动输入密码:基于SSHPass的自动化文件传输实践
一、运维人员的共同痛点 在日常运维工作中,我们经常需要在多台服务器之间传输文件。传统的手动操作方式需要反复执行以下步骤: 输入scp命令等待密码提示输入复杂密码确认传输结果手动修改文件权限 这种重复劳动不仅效率低下,在批量操作时更…...
Python序列Day3
序列 序列是一种数据存储方式,用方括号标注,逗号分隔的一组值。在内存中,序列就是一块用来存放多个值的连续的内存空间。 常见序列结构有:字符串、列表、元组、字典、集合 列表 用于存储任意数目,任意类型的数据集…...
22、近端策略优化算法(PPO)论文笔记
近端策略优化算法(PPO)论文笔记 一、研究背景与目标二、**方法****3.1 策略梯度基础****3.2 信任区域方法(TRPO)****3.3 剪切代理目标函数(LCLIP)****3.4 自适应KL惩罚系数****3.5 算法实现** 三、 L CLIP…...
web 自动化之 selenium+webdriver 环境搭建及原理讲解
文章目录 一、web 自动化测试学习说明二、什么 web 自动化测试三、selenium 简介四、web自动化测试环境搭建五、web 自动化测试第一个脚本六、selenium 原理及源码讲解 一、web 自动化测试学习说明 进阶 web 自动化测试学习:掌握 python 编程基础 二、什么 web 自…...
Vue3快速入门/Vue3基础速通
Vue3 渐进式的javascript框架,我们可以逐步引入vue的功能 官方文档 Vue.js中文手册 你可以借助 script 标签直接通过 CDN 来使用 Vue: <script src"https://unpkg.com/vue3/dist/vue.global.js"></script>通过 CDN 使用 Vue 时…...
Babylon.js学习之路《一、初识 Babylon.js:什么是 3D 开发与 WebGL 的完美结合?》
文章目录 1. 引言:3D 开发在 Web 中的崛起1.1 为什么需要 Web 3D 开发?1.1 WebGL 的定位与挑战 2. Babylon.js 的核心定位2.1 什么是 Babylon.js?2.2 Babylon.js 的独特优势2.3 对比其他 Web 3D 框架(Three.js、PlayCanvas&#x…...
v-model原理详解
一 :value"msg 在 Vue.js 中,v-bind 指令(简写为 :)用于将数据属性绑定到 HTML 元素的属性上。当你使用 :value"msg" 时,它的作用是将 Vue 实例中的 msg 数据属性绑定到目标元素的 value 属性上。 1.value 属性…...
并发与并行的关系
并发(Concurrency)与并行(Parallelism)的本质区别 1. 核心定义 并发:多个任务在重叠的时间段内交替执行,但不一定是同时的。 关注的是任务的组织方式(如多任务调度、逻辑上的同时性)…...
uniapp 微信小程序使用图表
使用的是秋云 ucharts 直接在hbuilder插件市场进行下载导入项目中,多端支持 下载地址秋云 ucharts echarts 高性能跨全端图表组件 - DCloud 插件市场 导入成功后这里就能看到导入的插件啦 导入项目后就可以直接在页面中通过组件使用了 不需要其余配置 使用简单 参…...
基于vm加密的php逆向分析
前言 对于 php 主流的加密方式有两种: 1、基于扩展的 2、本地加密,不涉及扩展 一些在 php 端通过 zend_compile_file 等函数就可以直接 dump 出原代码的,称之为加密实在是抬举了 之前有写过一篇直接 dump 出源码的分析 https://blog.qc7…...
FPGA----基于ALINX提供的debian实现TCF
引言:接上问,我们使用自制的image.ub和boot.bin以及ALINX提供的debian8根文件系统,构建了petalinux,但是经测试,该文件系统无法启用TCF服务,即无法与Xilinx SDK建立连接,那么我们应该如何解决&a…...
基于Transformer的多资产收益预测模型实战(附PyTorch实现与避坑指南)
基于Transformer的多资产收益预测模型实战(附PyTorch模型训练及可视化完整代码) 一、项目背景与目标 在量化投资领域,利用时间序列数据预测资产收益是核心任务之一。传统方法如LSTM难以捕捉资产间的复杂依赖关系,而Transformer架…...
SQL:MySQL函数:字符串函数
目录 为什么需要字符串函数? 1️⃣ LENGTH(str) — 这个字符串有几个“字节”? 2️⃣ CHAR_LENGTH(str) — 这个字符串有几个“字符”? 3️⃣ TRIM(str) — 把两边的空格剪掉 4️⃣ REPLACE(str, a, b) — 把 a 替换成 b 使用这些函数时…...
C++-缺省参数
缺省参数 缺省参数也叫默认参数 指的是在函数参数的位置,提前定义一个缺省值(即提前定义一个值),当函数接收到参数时,如果定义缺省值的位置未接收到参数,那么这个位置会自动使用缺省值 通过定义缺省参数…...
MySQL 数据库
目录 1. 数据库简介 1.1 使用数据库的必要性 1.2 数据库的基本概念 1.3 经典数据模型 2. MySQL 服务基础 2.1 MySQL 的二进制安装 2.1.1 基础环境准备 2.1.2 二进制安装 2.1.3 设定配置文件 1. 数据库简介 1.1 使用数据库的必要性 使用数据库可以高效且条理分明地存…...
探寻养生新路径,守护健康生活
在忙碌的现代生活中,人们对健康养生的需求愈发迫切。养生不一定要遵循复杂的规则,从一些新颖且实用的方面入手,同样能收获健康的馈赠。 关注肠道菌群的平衡是养生的关键。肠道内居住着数以万亿计的微生物,它们与人体健康息息相…...
平板收银系统、国产系统,鸿蒙系统,小键盘的封装与应用—仙盟创梦IDE
数字小键盘封装 数组小键盘封装是指将与数组小键盘相关的功能、操作、数据等进行整合,形成一个独立的、可复用的模块。封装数组小键盘具有以下几方面重要意义: 提高代码可维护性 降低复杂度:数组小键盘在实际应用中,可能涉及到…...
微软推动智能体协同运作:支持 A2A、MCP 协议
今日凌晨,微软宣布 Azure AI Foundry 和 Microsoft Copilot Studio 两大开发平台支持最新 Agent 开发协议 A2A,并与谷歌合作开发扩大该协议,这一举措对智能体赛道意义重大。 现状与变革意义 当前智能体领域类似战国时代,各家技术…...
《企业级前端部署方案:Jenkins+MinIO+SSH+Gitee+Jenkinsfile自动化实践》
文章目录 前言前端项目CICD时序图一、环境准备1、服务器相关2、Jenkins凭据3、注意事项 二、设计思想1. 模块化设计2.多环境支持3. 制品管理4. 安全部署机制5. 回滚机制 三、CI阶段1、构建节点选择2、代码拉取3、代码编译4、打包并上传至minio 四、CD阶段五、回滚阶段六、构建通…...
数据库的进阶操作
目录 1、数据库的约束 2、查询操作的进阶 2.1 查询插入 2.2 聚合查询 2.3 运算查询 2.3 分组查询 2.4 联合查询 2.5 内外连接 2.6 子查询 2.7 合并查询 1、数据库的约束 数据库的约束是指:数据库会自动的对数据的合法性进行校验和检查的一系列操作的机制&a…...
小刚说C语言刷题—1341银行存款问题
1.题目描述 亮亮把 n 元按照 m 年期整存存入银行,按照目前银行的年利率,请问到期后亮亮可以连本带息总共拿到多少钱? 存期(整存整取) 年利率 1年 3.25% 2年 3.75% 3年∼4 年 4.25% 5年及 5年以上 4.75% 输入…...
15 个 Azure DevOps 场景化面试问题及解答
问题 1. 解释 Azure DevOps YAML 管道的典型结构。 您可以从管道的整体结构开始,从触发器开始。您也可以选择解释它可能包含的不同类型的阶段:构建、测试、扫描、部署等。 Azure DevOps YAML 管道结构示例 触发器指示管道运行。它可以是持续集成 (CI) 或…...
spring cloud 跨服务调用
微服务将不同功能模块拆分成多个不同的服务,在业务逻辑集成时候,难免会有一个服务需要依赖调用另一个服务的情况。如订单服务需要通过用户服务查询用户相关信息,这时候微服务之间就需要进行跨服务调用。 要想进行跨服务调用,服务…...
手机隐私数据彻底删除工具:回收或弃用手机前防数据恢复
软件介绍 有这样一款由吾爱网友chenwangjun 原创开发的数据处理软件,名为 AndroidDiskClear。它的核心功能十分强大,能够将你手机里已经删除的各类文件,像图片、普通文件、文字信息等彻底清除干净,有效杜绝数据恢复类软件的二次恢…...
【Electron】electron-vue 借助 element-ui UI 库助力桌面应用开发
前面文章我们讲过 electron 让可以用 HTML、JS、CSS 开发桌面应用程序。而 electron-vue 是一个结合了 electron 与 vue 的套件。这样我们就能方便地使用 vue 快速开发桌面应用。但是,vue 只是在 js 这层面做了大量的便捷的操作。对 UI 并未过多涉及。此时如果您在开…...
《信息论与编码课程笔记》——信源编码(1)
目录 一、信源编码基本概念 1. 定义与目的 2. 编码示例 3. 编码分类 4. 唯一可译码的判断标准 5. 编码评价指标 二、香农第一定理(无失真可变长信源编码定理) 1. 核心内容 2. 关键概念与指标 3. 数据压缩的本质 4. 例子与启示 5. 定理的意义…...
2022年8月,韩先超对中移信息进行微服务架构原理(Docker+k8s+DevOps+Go等)培训
2022年8月,韩先超对中移信息进行微服务架构原理(Dockerk8sDevOpsGo等)培训 2022年8月,在企业数字化转型和云原生架构加速演进的背景下, 中移信息技术有限公司特别邀请云原生与DevOps领域专家 韩先超老师,…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】8.4 数据故事化呈现(报告结构设计/业务价值提炼)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 8.4 数据故事化呈现:从报告结构到业务价值的深度融合一、数据故事化的核心价值体系(一)报告结构设计的黄金框架1. 业务场景锚定ÿ…...
Docker 核心目录结构
1. Docker 核心目录结构 数据存储目录 默认根目录:/var/lib/docker Docker 所有运行时数据(镜像、容器、卷、网络配置等)的默认存储位置。 bash 复制 下载 # 查看 Docker 数据根目录 docker info | grep "Docker Root Dir" # 输出…...