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

青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型

青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型

  • 一、元组(Tuple)
    • (一)元组的定义
    • (二)创建元组
        • 示例
    • (三)解构元组
        • 示例
    • (四)使用点号语法访问元组元素
        • 示例
    • (五)元组的特点
      • 5.1 固定大小
      • 异构类型
      • 不可变
      • 可以嵌套
        • 示例
    • (六)元组的用途
      • 函数返回多个值
        • 示例
      • 临时组合数据
        • 示例
    • (七)元组的限制
      • 7.1 固定大小
      • 不支持动态索引
    • 元组类型总结
  • 二、数组(Array)
    • (一)数组的定义
    • (二)创建数组
      • 显式指定数组类型
      • 类型推断
      • 初始化数组
    • (三)访问数组元素
        • 示例
    • (四)数组的特点
      • 4.1 固定大小
      • 4.2 同构类型
      • 不可变
      • 索引访问
    • (五)可变数组
        • 示例
    • (六)数组的用途
      • 6.1 存储固定数量的同类型数据
      • 6.2 作为函数参数
        • 示例
      • 作为函数返回值
        • 示例
    • (七)数组的限制
      • 固定大小
      • 7.2 索引越界
        • 示例
    • (八)数组与向量的区别
    • 数组类型总结
  • 三、结构体(Struct)
    • (一)定义结构体
        • 示例
    • (二)创建结构体实例
        • 示例
    • (三)访问结构体字段
        • 示例
    • (四)修改结构体字段
        • 示例
    • (五)结构体的特点
      • 用户定义
      • 灵活的字段类型
      • 可变性
      • 方法关联
        • 示例
    • (六)结构体的用途
      • 表示实体
        • 示例
      • 6.2 作为函数参数
        • 示例
      • 6.3 作为函数返回值
        • 示例
    • (七)结构体的高级用法
      • 7.1 元组结构体
        • 示例
      • 7.2 单元结构体
        • 示例
      • 可视性
        • 示例
    • 结构体类型总结
  • 四、枚举(Enum)
    • (一)枚举的基本概念
      • 简单枚举
    • (二)携带数据的枚举变体
      • 匿名结构体
    • (三)为枚举定义方法
      • 示例
    • (四)模式匹配与枚举
      • 穷尽匹配检查
    • (五)特殊的枚举类型
      • Option 枚举
      • Result 枚举
    • (六)枚举的高级用法
      • 6.1 派生特性
      • 6.2 递归定义
    • 枚举类型总结
  • 五、综合示例
      • 运行结果
      • 示例说明
  • 复合数据类型总结

摘要:Rust 的复合数据类型包括元组、数组、结构体和枚举。这些类型允许你将多个值组合成一个更复杂的数据结构,从而更灵活地表示和处理数据。通过合理使用这些复合数据类型,可以提高代码的可读性和可维护性。

关键词:复合数据类型、元组、数组、结构体、枚举


在 Rust 中,复合数据类型(Composite Data Types)是由多个值组合而成的类型,这些值可以是相同类型,也可以是不同类型。复合数据类型允许你将多个相关的值组织在一起,形成一个更复杂的数据结构。Rust 提供了几种内置的复合数据类型,包括 元组(Tuple) 和 数组(Array),此外还有用户定义的 结构体(Struct) 和 枚举(Enum)。

一、元组(Tuple)

在 Rust 中,元组(Tuple)是一种非常灵活的复合数据类型,用于将多个值组合成一个逻辑单元。元组中的值可以是不同类型,这使得元组非常适合用于临时组合不同类型的数据。以下是对 Rust 中元组的详细解析。

(一)元组的定义

元组是一种将多个值组合成一个复合类型的方式。元组中的每个值可以有不同的类型。元组的大小和类型在编译时确定,因此元组的大小是固定的。

(二)创建元组

元组的语法是将多个值用圆括号 () 包裹起来,值之间用逗号 , 分隔。如果元组中只有一个值,需要在值后面加上一个逗号,以区分元组和普通的括号表达式。

示例
let tuple: (i32, f64, char) = (500, 6.4, 'J'); // 多个值的元组
let single_element_tuple: (i32,) = (42,);     // 单个值的元组

(三)解构元组

可以通过解构(Destructuring)的方式访问元组中的值。解构是将元组中的值分别赋给多个变量的过程。

示例
let tuple: (i32, f64, char) = (500, 6.4, 'J');// 解构元组
let (x, y, z) = tuple;println!("The value of x is: {}", x); // 输出 500
println!("The value of y is: {}", y); // 输出 6.4
println!("The value of z is: {}", z); // 输出 'J'

(四)使用点号语法访问元组元素

除了解构,还可以通过点号语法访问元组中的元素。元组中的每个元素都有一个索引,从 0 开始。

示例
let tuple: (i32, f64, char) = (500, 6.4, 'J');println!("The value of tuple.0 is: {}", tuple.0); // 输出 500
println!("The value of tuple.1 is: {}", tuple.1); // 输出 6.4
println!("The value of tuple.2 is: {}", tuple.2); // 输出 'J'

(五)元组的特点

5.1 固定大小

元组的大小在编译时确定,一旦定义,不能改变。

异构类型

元组中的元素可以是不同类型,这使得元组非常适合用于临时组合不同类型的数据。

不可变

默认情况下,元组是不可变的。如果需要修改元组中的值,必须将元组声明为可变的(mut)。

可以嵌套

元组可以嵌套,即元组的元素可以是另一个元组。

示例
let nested_tuple: ((i32, f64), char) = ((500, 6.4), 'J');// 访问嵌套元组
println!("The value of nested_tuple.0.0 is: {}", nested_tuple.0.0); // 输出 500
println!("The value of nested_tuple.0.1 is: {}", nested_tuple.0.1); // 输出 6.4
println!("The value of nested_tuple.1 is: {}", nested_tuple.1);     // 输出 'J'

(六)元组的用途

函数返回多个值

元组非常适合用于函数返回多个值的情况。一个函数可以返回一个元组,调用者可以通过解构来获取这些值。

示例
fn get_user_info() -> (String, i32, bool) {(String::from("Alice"), 30, true)
}fn main() {let (name, age, is_active) = get_user_info();println!("Name: {}, Age: {}, Active: {}", name, age, is_active);
}

临时组合数据

元组可以用于临时组合不同类型的数据,例如在循环中同时处理多个值。

示例
let point: (i32, i32) = (10, 20);for (x, y) in [(0, 0), (1, 1), (2, 2)] {println!("Point: ({}, {})", x, y);
}

(七)元组的限制

7.1 固定大小

元组的大小在编译时确定,一旦定义,不能改变。如果需要动态大小的数据结构,应该使用数组或向量(Vec)。

不支持动态索引

元组不支持动态索引,只能通过点号语法访问固定索引的元素。如果需要动态访问元素,应该使用数组或向量。

元组类型总结

Rust 的元组是一种非常灵活的复合数据类型,用于将多个值组合成一个逻辑单元。元组的特点包括固定大小、异构类型、不可变性以及支持嵌套。通过合理使用元组,可以方便地处理多个不同类型的数据,尤其是在函数返回多个值或临时组合数据的场景中。

二、数组(Array)

在 Rust 中,数组(Array)是一种固定大小的序列,其中的每个元素都必须是相同的类型。数组的大小在编译时确定,因此数组的大小是其类型的一部分。数组在 Rust 中非常有用,尤其是在需要存储固定数量的同类型数据时。以下是对 Rust 中数组的详细解析。

(一)数组的定义

数组是一种将多个相同类型的值组合成一个逻辑单元的方式。数组的大小和类型在编译时确定,因此数组的大小是固定的。

(二)创建数组

数组的语法是将多个值用方括号 [] 包裹起来,值之间用逗号 , 分隔。数组的类型由元素的类型和数组的长度共同决定。

显式指定数组类型

let array: [i32; 5] = [1, 2, 3, 4, 5];

在这个例子中,[i32; 5] 表示数组的类型,其中 i32 是元素的类型,5 是数组的长度。

类型推断

如果数组的类型可以由编译器推断,可以省略类型注解:

let array = [1, 2, 3, 4, 5]; // 编译器推断类型为 [i32; 5]

初始化数组

可以使用重复语法初始化数组,即用一个值初始化数组的所有元素:

let array = [0; 5]; // 初始化一个所有元素都是 0 的数组,类型为 [i32; 5]

(三)访问数组元素

可以通过索引访问数组中的元素。数组索引从 0 开始。

示例
let array = [1, 2, 3, 4, 5];
println!("The value of array[0] is: {}", array[0]); // 输出 1
println!("The value of array[4] is: {}", array[4]); // 输出 5

(四)数组的特点

4.1 固定大小

数组的大小在编译时确定,一旦定义,不能改变。数组的大小是其类型的一部分。

4.2 同构类型

数组中的所有元素必须是相同的类型。

不可变

默认情况下,数组是不可变的。如果需要修改数组中的值,必须将数组声明为可变的(mut)。

索引访问

可以通过索引访问数组中的元素。数组索引从 0 开始。

(五)可变数组

如果需要修改数组中的值,必须将数组声明为可变的(mut)。

示例
let mut array = [1, 2, 3, 4, 5];
array[0] = 10; // 修改数组中的第一个元素
println!("The value of array[0] is: {}", array[0]); // 输出 10

(六)数组的用途

6.1 存储固定数量的同类型数据

数组非常适合用于存储固定数量的同类型数据,例如存储一组整数、浮点数或字符。

6.2 作为函数参数

数组可以作为函数的参数传递,函数可以访问或修改数组中的值。

示例
fn print_array(arr: &[i32]) {for &element in arr {println!("{}", element);}
}fn main() {let array = [1, 2, 3, 4, 5];print_array(&array);
}

作为函数返回值

数组也可以作为函数的返回值。

示例
fn get_array() -> [i32; 5] {[1, 2, 3, 4, 5]
}fn main() {let array = get_array();println!("{:?}", array); // 输出 [1, 2, 3, 4, 5]
}

(七)数组的限制

固定大小

数组的大小在编译时确定,一旦定义,不能改变。如果需要动态大小的数据结构,应该使用向量(Vec)。

7.2 索引越界

访问数组时,如果索引超出数组的范围,会导致运行时错误(panic)。为了避免这种情况,可以使用 get 方法,它返回一个 Option 类型,而不是直接访问元素。

示例
let array = [1, 2, 3, 4, 5];
let index = 5;match array.get(index) {Some(value) => println!("The value at index {} is: {}", index, value),None => println!("Index {} out of bounds", index),
}

(八)数组与向量的区别

Rust 中的数组和向量(Vec)有一些重要的区别:

  • 数组:
    • 固定大小:大小在编译时确定,不能改变。
    • 同构类型:所有元素必须是相同的类型。
    • 不可变:默认情况下,数组是不可变的。
  • 向量:
    • 动态大小:大小可以在运行时改变。
    • 同构类型:所有元素必须是相同的类型。
    • 可变:向量默认是可变的。

数组类型总结

Rust 的数组是一种固定大小的序列,其中的每个元素都必须是相同的类型。数组的大小在编译时确定,因此数组的大小是其类型的一部分。数组的特点包括固定大小、同构类型、不可变性以及支持索引访问。通过合理使用数组,可以方便地存储和处理固定数量的同类型数据。如果需要动态大小的数据结构,应该使用向量(Vec)。

三、结构体(Struct)

在 Rust 中,结构体(Struct) 是一种用户定义的复合数据类型,用于将多个值组合成一个逻辑单元。结构体允许你将相关的数据组织在一起,形成一个更复杂的类型。结构体中的每个字段都有自己的名称和类型,这使得结构体非常适合用于表示具有多个属性的实体。

(一)定义结构体

结构体使用 struct 关键字定义,后面跟着结构体的名称和一组花括号 {},花括号内定义了结构体的字段。

示例
struct Person {name: String,age: u32,is_active: bool,
}

在这个例子中,Person 是一个结构体,它有三个字段:

  • name:类型为 String
  • age:类型为 u32
  • is_active:类型为 bool

(二)创建结构体实例

创建结构体实例时,需要使用结构体的名称,并为每个字段提供一个值。

示例
let person = Person {name: String::from("Alice"),age: 30,is_active: true,
};

在这个例子中,person 是一个 Person 类型的实例,它的字段分别被初始化为 "Alice"30true

(三)访问结构体字段

可以通过点号语法(.)访问结构体中的字段。

示例
println!("Name: {}", person.name);
println!("Age: {}", person.age);
println!("Is active: {}", person.is_active);

(四)修改结构体字段

默认情况下,结构体实例是不可变的。如果需要修改结构体中的字段,必须将结构体声明为可变的(mut)。

示例
let mut person = Person {name: String::from("Alice"),age: 30,is_active: true,
};person.age = 31; // 修改 age 字段
println!("Updated age: {}", person.age);

(五)结构体的特点

用户定义

结构体是用户定义的类型,可以根据需要定义字段。

灵活的字段类型

结构体中的字段可以是不同类型,这使得结构体非常适合用于表示具有多个属性的实体。

可变性

结构体的字段可以是可变的,也可以是不可变的,具体取决于字段的声明。

方法关联

可以为结构体定义方法,通过 impl 块将方法与结构体关联起来。

示例
impl Person {fn new(name: String, age: u32, is_active: bool) -> Self {Person { name, age, is_active }}fn greet(&self) {println!("Hello, my name is {} and I am {} years old.", self.name, self.age);}
}fn main() {let person = Person::new(String::from("Alice"), 30, true);person.greet();
}

在这个例子中:

  • new 方法用于创建 Person 实例。
  • greet 方法用于打印问候信息。

(六)结构体的用途

表示实体

结构体非常适合用于表示具有多个属性的实体,例如用户、产品、配置等。

示例
struct Product {id: u32,name: String,price: f64,
}let product = Product {id: 1,name: String::from("Laptop"),price: 999.99,
};

6.2 作为函数参数

结构体可以作为函数的参数传递,函数可以访问或修改结构体中的字段。

示例
fn print_product(product: &Product) {println!("Product ID: {}", product.id);println!("Product Name: {}", product.name);println!("Product Price: ${}", product.price);
}fn main() {let product = Product {id: 1,name: String::from("Laptop"),price: 999.99,};print_product(&product);
}

6.3 作为函数返回值

结构体也可以作为函数的返回值。

示例
fn create_product() -> Product {Product {id: 1,name: String::from("Laptop"),price: 999.99,}
}fn main() {let product = create_product();println!("Product Name: {}", product.name);
}

(七)结构体的高级用法

7.1 元组结构体

元组结构体是一种特殊的结构体,它的字段没有名称,只有类型。元组结构体的语法类似于元组。

示例
struct Color(u8, u8, u8);let black = Color(0, 0, 0);
println!("Red: {}, Green: {}, Blue: {}", black.0, black.1, black.2);

7.2 单元结构体

单元结构体是一种没有字段的结构体,通常用于实现 trait 或作为标记类型。

示例
struct Null;impl Null {fn new() -> Self {Null}fn greet(&self) {println!("Hello from Null!");}
}fn main() {let null = Null::new();null.greet();
}

可视性

结构体的字段可以是私有的(private)或公有的(pub)。默认情况下,结构体的字段是私有的。

示例
pub struct Person {pub name: String,age: u32, // 私有字段
}impl Person {pub fn new(name: String, age: u32) -> Self {Person { name, age }}pub fn greet(&self) {println!("Hello, my name is {} and I am {} years old.", self.name, self.age);}
}fn main() {let person = Person::new(String::from("Alice"), 30);println!("Name: {}", person.name); // 可以访问公有字段// println!("Age: {}", person.age); // 错误:age 字段是私有的person.greet();
}

结构体类型总结

Rust 的结构体是一种非常强大的复合数据类型,用于将多个值组合成一个逻辑单元。结构体的特点包括用户定义、灵活的字段类型、可变性以及支持方法关联。通过合理使用结构体,可以方便地表示具有多个属性的实体,并在程序中灵活地处理这些数据。

四、枚举(Enum)

在 Rust 中,枚举(Enum) 是一种非常强大的特性,它允许你通过列举可能的成员来定义一个类型。每个成员称为 变体(Variant),变体可以携带不同类型的数据。枚举在 Rust 中广泛应用于错误处理、状态机、事件驱动编程等场景。

(一)枚举的基本概念

枚举是一种用户自定义的类型,它将一组可能的值组合在一起。每个值称为一个变体,变体可以携带不同类型的数据。

简单枚举

enum ConnectionState {Disconnected,Connecting,Connected,Reconnecting(u8), // 携带重试次数
}

在这个例子中,DisconnectedConnectingConnectedReconnecting 都是枚举的变体。

(二)携带数据的枚举变体

枚举的变体可以携带不同类型的数据,这使得枚举非常灵活。

匿名结构体

enum Message {Move { x: i32, y: i32 }, // 匿名结构体Write(String),          // 字符串ChangeColor(i32, i32, i32), // 元组
}
  • Move 是一个匿名结构体,包含两个字段 xy
  • Write 是一个携带 String 的变体。
  • ChangeColor 是一个携带三个 i32 的变体。

(三)为枚举定义方法

可以为枚举定义方法,通过 impl 块将方法与枚举关联起来。

示例

impl Message {fn process(&self) {match self {Message::Move { x, y } => println!("Move to ({}, {})", x, y),Message::Write(text) => println!("Write: {}", text),Message::ChangeColor(r, g, b) => println!("Change color to ({}, {}, {})", r, g, b),}}
}

(四)模式匹配与枚举

枚举与模式匹配结合使用,可以方便地根据变体进行分支处理并提取数据。

穷尽匹配检查

fn handle_state(state: &ConnectionState) {match state {ConnectionState::Disconnected => println!("连接已断开"),ConnectionState::Connecting => println!("连接中..."),ConnectionState::Connected => println!("连接成功"),ConnectionState::Reconnecting(attempts) => println!("第 {} 次重连中", attempts),}
}

match 表达式中,必须穷尽所有可能的模式。

(五)特殊的枚举类型

Rust 标准库中有一些特殊的枚举类型,例如 Option<T>Result<T, E>

Option 枚举

Option<T> 枚举用于处理可能为空的值,包含两个成员:

  • Some(T):表示包含一个值。
  • None:表示没有值。

Result 枚举

Result<T, E> 枚举用于错误处理,包含两个成员:

  • Ok(T):表示操作成功,包含一个值。
  • Err(E):表示操作失败,包含一个错误。

(六)枚举的高级用法

6.1 派生特性

可以为枚举派生一些特性,例如 DebugClone 等。

#[derive(Debug, Clone)]
enum Animal {Dog,Cat,
}

6.2 递归定义

枚举可以递归定义,例如定义一个二叉树。

enum Tree<T> {Node(T, Box<Tree<T>>, Box<Tree<T>>),Empty,
}

枚举类型总结

枚举是 Rust 中一种非常灵活的类型,它不仅可以表示一组可能的值,还可以携带不同类型的数据。枚举与模式匹配结合使用,可以实现强大的逻辑控制。通过合理使用枚举,可以提高代码的类型安全性和可读性。

五、综合示例

以下是一个综合示例,展示了 Rust 中元组、数组、结构体和枚举的定义和使用:

// 定义一个元组
fn tuple_example() {// 创建元组let tuple: (i32, f64, char) = (500, 6.4, 'J');// 解构元组let (x, y, z) = tuple;println!("The value of x is: {}", x); // 输出 500println!("The value of y is: {}", y); // 输出 6.4println!("The value of z is: {}", z); // 输出 'J'// 使用点号语法访问元组元素println!("The value of tuple.0 is: {}", tuple.0); // 输出 500println!("The value of tuple.1 is: {}", tuple.1); // 输出 6.4println!("The value of tuple.2 is: {}", tuple.2); // 输出 'J'// 元组嵌套let nested_tuple: ((i32, f64), char) = ((500, 6.4), 'J');println!("The value of nested_tuple.0.0 is: {}", nested_tuple.0.0); // 输出 500println!("The value of nested_tuple.0.1 is: {}", nested_tuple.0.1); // 输出 6.4println!("The value of nested_tuple.1 is: {}", nested_tuple.1); // 输出 'J'
}// 定义一个数组
fn array_example() {// 创建数组let array: [i32; 5] = [1, 2, 3, 4, 5];println!("The value of array[0] is: {}", array[0]); // 输出 1println!("The value of array[4] is: {}", array[4]); // 输出 5// 创建可变数组并修改元素let mut mutable_array = [1, 2, 3, 4, 5];mutable_array[0] = 10;println!("The value of mutable_array[0] is: {}", mutable_array[0]); // 输出 10// 使用 get 方法安全访问数组元素let index = 5;match array.get(index) {Some(value) => println!("The value at index {} is: {}", index, value),None => println!("Index {} out of bounds", index),}
}// 定义一个结构体
struct Person {name: String,age: u32,is_active: bool,
}impl Person {fn new(name: String, age: u32, is_active: bool) -> Self {Person { name, age, is_active }}fn greet(&self) {println!("Hello, my name is {} and I am {} years old.", self.name, self.age);}
}fn struct_example() {// 创建结构体实例let person = Person::new(String::from("Alice"), 30, true);person.greet();// 访问结构体字段println!("Name: {}", person.name);println!("Age: {}", person.age);println!("Is active: {}", person.is_active);// 修改结构体字段let mut mutable_person = Person::new(String::from("Bob"), 25, false);mutable_person.age = 26;println!("Updated age: {}", mutable_person.age);
}// 定义一个枚举
enum ConnectionState {Disconnected,Connecting,Connected,Reconnecting(u8), // 携带重试次数
}impl ConnectionState {fn process(&self) {match self {ConnectionState::Disconnected => println!("连接已断开"),ConnectionState::Connecting => println!("连接中..."),ConnectionState::Connected => println!("连接成功"),ConnectionState::Reconnecting(attempts) => println!("第 {} 次重连中", attempts),}}
}fn enum_example() {// 创建枚举实例并调用 process 方法let disconnected = ConnectionState::Disconnected;disconnected.process();let connecting = ConnectionState::Connecting;connecting.process();let connected = ConnectionState::Connected;connected.process();let reconnecting = ConnectionState::Reconnecting(3);reconnecting.process();
}fn main() {println!("Tuple Example:");tuple_example();println!("\nArray Example:");array_example();println!("\nStruct Example:");struct_example();println!("\nEnum Example:");enum_example();
}

运行结果

Tuple Example:
The value of x is: 500
The value of y is: 6.4
The value of z is: J
The value of tuple.0 is: 500
The value of tuple.1 is: 6.4
The value of tuple.2 is: J
The value of nested_tuple.0.0 is: 500
The value of nested_tuple.0.1 is: 6.4
Array Example:ested_tuple.1 is: J
The value of array[0] is: 1
The value of array[4] is: 5
The value of mutable_array[0] is: 10
Struct Example:bounds
Hello, my name is Alice and I am 30 years old.
Name: Alice
Age: 30
Is active: true
Updated age: 26Enum Example:
连接已断开
连接中...
连接成功
第 3 次重连中

示例说明

  1. 元组

    • 创建元组并解构。
    • 使用点号语法访问元组元素。
    • 展示了元组嵌套的使用。
  2. 数组

    • 创建固定大小的数组并访问元素。
    • 创建可变数组并修改元素。
    • 使用 get 方法安全访问数组元素。
  3. 结构体

    • 定义了一个 Person 结构体,包含 nameageis_active 字段。
    • 实现了 new 方法用于创建结构体实例和 greet 方法用于打印问候信息。
    • 展示了如何访问和修改结构体字段。
  4. 枚举

    • 定义了一个 ConnectionState 枚举,包含多个变体,其中 Reconnecting 变体携带一个 u8 类型的数据。
    • 实现了 process 方法,通过模式匹配处理不同的枚举变体。

运行此代码将展示 Rust 中复合数据类型的定义和使用方法。

复合数据类型总结

Rust 中的复合数据类型包括元组、数组、结构体和枚举。元组用于组合不同类型的数据,通过索引访问元素;数组存储固定大小的同类型数据,通过索引访问,大小在编译时确定;结构体是用户定义的类型,将多个字段组合成逻辑单元,字段有名称和类型,支持方法关联;枚举定义一组可能的值,每个值称为变体,变体可携带不同类型数据,常与模式匹配结合使用。这些复合数据类型为 Rust 提供了强大的数据组织能力,适用于多种编程场景,增强了代码的灵活性和可维护性。

相关文章:

青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型

青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型 一、元组&#xff08;Tuple&#xff09;&#xff08;一&#xff09;元组的定义&#xff08;二&#xff09;创建元组示例 &#xff08;三&#xff09;解构元组示例 &#xff08;四&#xff09;使用点号语法访问元组…...

51单片机入门教程——AT24C02数据存储

前言 本教程基于B站江协科技课程进行个人学习整理&#xff0c;专为拥有C语言基础的零基础入门51单片机新手设计。既帮助解决因时间差导致的设备迭代调试难题&#xff0c;也助力新手快速掌握51单片机核心知识&#xff0c;实现从C语言理论到单片机实践应用的高效过渡 。 目录 …...

cdn 是什么?

内容分发网络&#xff0c;Content Delivery Network 介绍 CDN&#xff08;Content Delivery Network&#xff09;是一种将内容分发到靠近用户的边缘服务器&#xff0c;以加速访问速度、减少延迟、降低源站压力的网络系统。 CDN 把网站的静态资源&#xff08;如 HTML、JS、CSS、…...

ENSP三层交换机实验原理及过程

华为eNSP&#xff08;Enterprise Network Simulation Platform&#xff09;是一款网络仿真工具&#xff0c;用于模拟华为网络设备的配置和操作。在三层交换机实验中&#xff0c;主要涉及三层交换机的路由功能、VLAN间通信、静态路由、动态路由协议&#xff08;如OSPF、RIP&…...

RK3568-OpenHarmony(1) : OpenHarmony 5.1的编译

概述: 本文主要描述了&#xff0c;如何在ubuntu-20.04操作系统上&#xff0c;编译RK3568平台的OpenHarmony 5.1版本。 搭建编译环境 a. 安装软件包 sudo apt-get install git-lfs ruby genext2fs build-essential git curl libncurses5-dev libncursesw5-dev openjdk-11-jd…...

动态路由EIGRP的配置

动态路由EIGRP的配置 动态路由EIGRP&#xff1a;增强内部网关协议 为何收敛快、不成环&#xff1f; 路由计算的无环路和路由的收敛速度是路由计算的重要指标。EIGRP协议由于使用了DUAL算法&#xff0c;使得EIGRP协议在路由计算中不可能有环路路由产生&#xff0c;同时路由计…...

Paging 3.0 + Kotlin 分页加载指南

Paging 3.0 是 Android Jetpack 组件中用于高效分页加载数据的现代化方案&#xff0c;结合 Kotlin 协程和 Flow 特性&#xff0c;能够显著简化分页逻辑的实现。以下是完整的实现指南和最佳实践&#xff1a; 一、Paging 3.0 核心优势 内置加载状态管理&#xff1a;自动跟踪加载…...

湖南(源点咨询)市场调研 商业综合体定位调研分享(下篇)

接着中篇&#xff0c;我们就要重点分析一下该地区消费者的特点&#xff1a; 综合来看&#xff0c;本地区还是以中等收入工薪阶层的新市民家庭为主&#xff0c;以亲子关系为家庭核心&#xff0c;居住条件改善、生活向好&#xff0c;渴望公共配套的提升丰富生活质感&#xff0c;…...

vue 中的ref

vue 中的ref vue 中的ref 1. ​​ref​​ ** 的基本作用** 在 Vue 中&#xff0c;ref 是用来获取 DOM 元素或者组件实例的一种方式。对于 <el-form> 组件&#xff0c;通过 ref 可以获取到该表单组件的实例&#xff0c;进而调用表单组件提供的各种方法和访问其属性。 …...

Kotlin 协程 vs RxJava vs 线程池:性能与场景对比

1. 轻量级任务&#xff1a;10,000 个并发延迟操作 假设需要并发执行 10,000 个非阻塞延迟任务&#xff08;如模拟定时请求&#xff09;&#xff1a; 线程池实现 ExecutorService executor Executors.newFixedThreadPool(64); // 最多 64 线程 List<Future<?>>…...

golang-ErrGroup用法以及源码解读笔记

介绍 ErrGroup可以并发执行多个goroutine&#xff0c;并可以很方便的处理错误 与sync.WaitGroup相比 错误处理 sync.WaitGroup只负责等待goroutine执行完成&#xff0c;而不处理返回值或者错误errgroup.Group目前虽然不能直接处理函数的返回值或错误。但是当goroutine返回错…...

遗传算法组卷系统实现(Java版)

遗传算法组卷系统实现&#xff08;Java版&#xff09; 下面是一个完整的遗传算法组卷系统的Java实现&#xff0c;包含题目表示、适应度计算、选择、交叉和变异等核心操作。 1. 核心类设计 1.1 题目实体类&#xff08;Question.java&#xff09; public class Question {pri…...

JVM 逃逸分析

JVM逃逸分析&#xff1a;让Java对象"乖乖听话"的侦探游戏 大家好&#xff01;我是你们的老朋友"代码神探福尔摩斯"&#xff0c;今天要带大家破解一个JVM界的经典悬案——如何让Java对象乖乖待在它该待的地方&#xff1f; 第一章&#xff1a;案发现场——…...

第三天——贪心算法——区间问题

题目描述 给定多个区间&#xff0c;计算让这些区间互不重叠所需要移除区间的最少个数。起止相连不算重叠。 输入输出样例 输入是一个数组&#xff0c;包含多个长度固定为的子数组&#xff0c;表示每个区间的开始和结尾。输出一个 整数&#xff0c;表示需要移除的区间数量。 …...

路由重发布

路由重发布 实验目标&#xff1a; 掌握路由重发布的配置方法和技巧&#xff1b; 掌握通过路由重发布方式实现网络的连通性&#xff1b; 熟悉route-pt路由器的使用方法&#xff1b; 实验背景&#xff1a;假设学校的某个分区需要配置简单的rip协议路由信息&#xff0c;而主校…...

嵌入式与物联网:C 语言在边缘计算时代的破局之道

引言 在万物互联的 2025 年&#xff0c;全球物联网设备连接数突破 300 亿台&#xff0c;其中 78% 的嵌入式控制系统仍基于 C 语言开发。这种跨越半个世纪的编程语言&#xff0c;正以新的技术形态在智能汽车、工业物联网、边缘计算等领域重塑竞争力。本文通过三个前沿应用场景&…...

计算机网络:WiFi路由器发射的电磁波在空气中的状态是什么样的?

WiFi路由器发射的电磁波是高频无线电波,属于微波频段(2.4GHz或5GHz),在空气中以光速传播(约310⁸米/秒),其传播状态和特性可通过以下维度详细解析: 一、电磁波的物理特性 频率与波长 2.4GHz频段:波长约12.5厘米,穿透力较强但易受干扰(微波炉、蓝牙等共用频段)。5GH…...

使用FastAPI和Apache Flink构建跨环境数据管道

系统概述 本文介绍如何使用FastAPI微服务、Apache Flink和AWS ElastiCache Redis构建一个可扩展的数据管道&#xff0c;实现本地Apache Hive数据仓库与AWS云上Redis之间的数据交互。 该架构通过FastAPI提供RESTful接口&#xff0c;Apache Flink处理数据流&#xff0c;实现了本…...

解决 SQL Server 2008 导入 Excel 表卡在“正在初始化数据流”问题

在使用 SQL Server 2008 导入 Excel 表时&#xff0c;可能会遇到卡在“正在初始化数据流”这一令人困扰的情况。笔者近期也遭遇了同样的问题&#xff0c;尝试了多种常规方法均未解决&#xff0c;最终通过特定命令成功化解难题&#xff0c;在此分享解决过程与经验。 一、问题描…...

【Linux系统】从零开始构建简易 Shell:从输入处理到命令执行的深度剖析

文章目录 前言一、打印命令行提示符代码功能概述 二、读取键盘输入的指令2.1 为什么不继续使用scanf()而换成了fgets()&#xff1f;2.2 调试输出的意义2.3 为什么需要去掉换行符&#xff1f; 三、指令切割补充知识&#xff1a; strtok 的函数原型 四、普通命令的执行代码功能概…...

SSRF服务端请求伪造

SSRF&#xff1a;服务端请求伪造 危害&#xff1a;任意文件读取、任意服务探测&#xff08;通过端口来探测&#xff09; 例&#xff1a;探测3306端口&#xff0c;看mysql服务是否开启&#xff0c;再通过文件读取&#xff0c;获得mysql配置文件 例&#xff1a;当我们点击链接…...

LVGL的三层屏幕结构

文章目录 &#x1f31f; LVGL 的三层屏幕架构1. **Top Layer&#xff08;顶层&#xff09;**2. **System Layer&#xff08;系统层&#xff09;**3. **Active Screen&#xff08;当前屏幕层&#xff09;** &#x1f9e0; 总结对比&#x1f50d; 整体作用✅ 普通屏幕层对象&…...

使用互斥锁保护临界

Linux线程互斥及相关概念解析 1. 临界资源&#xff08;Critical Resource&#xff09; 定义&#xff1a;被多个线程共享的资源&#xff08;如变量、文件、内存区域等&#xff09;&#xff0c;需通过互斥访问确保数据一致性。特点&#xff1a; 共享性&#xff1a;多个线程可能…...

5.8线性动态规划2

P1004 [NOIP 2000 提高组] 方格取数 做法1&#xff1a;DFS剪枝 #include<bits/stdc.h> using namespace std; int n, a[10][10], maxs, minx 11, miny 11, maxx, maxy; void dfs(int x, int y, int s, int type){if(type 1 && x minx && y miny){…...

linux系统Ubuntn界面更改为中文显示,配置流程

Linux 系统是一种开源的、多用户的、多任务的操作系统&#xff0c;具有高度的稳定性、安全性和灵活性&#xff0c;被广泛应用于服务器、嵌入式系统、科研、教育以及个人电脑等领域。以下是关于 Linux 系统的一些基本信息&#xff1a; 发展历程&#xff1a;Linux 的发展始于 19…...

Looper死循环阻塞为什么没有ANR

Looper 死循环阻塞没有 ANR 的原因在于 ANR (Application Not Responding) 的检测机制依赖于特定线程的事件处理超时。以下是详细解释&#xff1a; 1. ANR 的触发机制&#xff1a; 主线程 (UI 线程) 阻塞&#xff1a; ANR 最常见的情况是主线程阻塞。Android 系统会监控主线程…...

数字孪生陆上风电场可视化管理系统

图扑软件搭建陆上风电场数字孪生平台&#xff0c;通过高精度建模与实时数据采集&#xff0c;1:1 还原风机设备、输电网络及场区环境。动态展示风机运行参数、发电量、设备健康状态等信息&#xff0c;实现风电场运维管理的智能化、可视化与高效化。...

图像处理篇---MJPEG视频流处理

文章目录 前言一、MJPEG流基础概念MJPEG流特点格式简单无压缩时序HTTP协议传输边界标记 常见应用场景IP摄像头视频流嵌入式设备&#xff08;如ESP32&#xff09;视频输出简单视频监控系统 二、基础处理方法方法1&#xff1a;使用OpenCV直接读取优点缺点 方法2&#xff1a;手动解…...

ensp的华为小实验

1.先进行子网划分 2.进行接口的IP地址配置和ospf的简易配置&#xff0c;先做到全网小通 3.进行ospf优化 对区域所有区域域间路由器进行一个汇总 对区域1进行优化 对区域2.3进行nssa设置 4.对ISP的路由进行协议配置 最后ping通5.5.5.5...

webpack和vite区别

webpack将文件视为模块打包 &#xff0c;从入口文件递归解析依赖&#xff0c;生成依赖图&#xff0c;使用loader处理非JS模块&#xff0c;最终输出到dist目录 因为要解析所有依赖&#xff0c;所以他启动慢 vite利用浏览器对于es模块的原生支持&#xff0c;利用ESM能力&#x…...

从父类到子类:C++ 继承的奇妙旅程(2)

前言&#xff1a; 各位代码航海家&#xff0c;欢迎回到C继承宇宙&#xff01;上回我们解锁了继承的「基础装备包」&#xff0c;成功驯服了public、protected和花式成员隐藏术。但—— ⚠️前方高能预警&#xff1a; 继承世界的暗流涌动远不止于此&#xff01;今天我们将勇闯三大…...

ScaleTransition 是 Flutter 中的一个动画组件,用于实现缩放动画效果。

ScaleTransition 是 Flutter 中的一个动画组件&#xff0c;用于实现缩放动画效果。它允许你对子组件进行动态的缩放变换&#xff0c;从而实现平滑的动画效果。ScaleTransition 通常与 AnimationController 和 Tween 一起使用&#xff0c;以控制动画的开始、结束和过渡效果。 基…...

部署RocketMQ

部署环境&#xff1a;jdk8以上&#xff0c;Linux系统 下载和安装指令&#xff1a; wget https://archive.apache.org/dist/rocketmq/4.9.4/rocketmq-all-4.9.4-bin-release.zip 显示下载成功&#xff1a; --2025-05-10 11:34:46-- https://archive.apache.org/dist/rocketm…...

从爬虫到网络---<基石9> 在VPS上没搞好Docker项目,把他卸载干净

1.停止并删除所有正在运行的容器 docker ps -a # 查看所有容器 docker stop $(docker ps -aq) # 停止所有容器 docker rm $(docker ps -aq) # 删除所有容器如果提示没有找到容器&#xff0c;可以忽略这些提示。 2.删除所有镜像 docker images # 查看所有镜像 dock…...

每日c/c++题 备战蓝桥杯(P2241 统计方形(数据加强版))

洛谷P2241 统计方形&#xff08;数据加强版&#xff09;题解 题目描述 给定一个 n m n \times m nm 的方格棋盘&#xff0c;要求统计其中包含的正方形数量和长方形数量&#xff08;不包含正方形&#xff09;。输入为两个正整数 n n n 和 m m m&#xff0c;输出两个整数分…...

LLaVA:开源多模态大语言模型深度解析

一、基本介绍 1.1 项目背景与定位 LLaVA(Large Language and Vision Assistant)是由Haotian Liu等人开发的开源多模态大语言模型,旨在实现GPT-4级别的视觉-语言交互能力。该项目通过视觉指令微调技术,将预训练的视觉编码器与语言模型深度融合,在多个多模态基准测试中达到…...

基于Spring Boot + Vue的母婴商城系统( 前后端分离)

一、项目背景介绍 随着母婴行业在互联网平台的快速发展&#xff0c;越来越多的家庭倾向于在线选购母婴产品。为了提高商品管理效率和用户购物体验&#xff0c;本项目开发了一个基于 Spring Boot Vue 技术栈的母婴商城系统&#xff0c;实现了商品分类、商品浏览、资讯展示、评…...

HNUST湖南科技大学-软件测试期中复习考点(保命版)

使用说明&#xff1a;本复习考点仅用于及格保命。软件测试和其他专业课不太一样&#xff0c;记忆的太多了&#xff0c;只能说考试的时候&#xff0c;想到啥就写啥&#xff0c;多写一点&#xff01;多写一点&#xff01;多写一点&#xff01;&#xff08;重要事情说三遍&#xf…...

【AI智能推荐系统】第七篇:跨领域推荐系统的技术突破与应用场景

第七篇:跨领域推荐系统的技术突破与应用场景 提示语:🔥 “打破数据孤岛,实现1+1>2的推荐效果!深度解析美团、亚马逊如何用跨领域推荐技术实现业务协同,知识迁移核心技术全公开!” 目录 跨领域推荐的商业价值跨领域推荐技术体系 2.1 基于共享表征的学习2.2 迁移学习…...

【现代深度学习技术】注意力机制04:Bahdanau注意力

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…...

使用FastAPI和React以及MongoDB构建全栈Web应用01 概述

Are you ready to craft digital experiences that captivate and convert? 您准备好打造令人着迷并能带来转变的数字体验了吗&#xff1f; In a world driven by innovation, the demand for robust and scalable web applications has never been higher. Whether you’re…...

Flutter - UIKit开发相关指南 - 概览

环境 Flutter 3.29 macOS Sequoia 15.4.1 Xcode 16.3 概览 UIView与Widgets的比较 在UIKit使用UIView类的对象进行页面开发,布局也是UIView类的对象,在Flutter中使用的是Widget,在概念上Widget可以理解成UIView。 差异&#xff1a; 有效期: Widgets是不可变的,它的生存期只…...

扩容 QCOW2 磁盘镜像文件

&#x1f308; 个人主页&#xff1a;Zfox_ 目录 ✅ 一、扩展 QCOW2 文件大小✅ 二、启动虚拟机后扩展分区和文件系统方式一&#xff1a;如果使用的是标准分区&#xff08;如 /dev/vda1&#xff09;方式二&#xff1a;使用 gparted&#xff08;图形工具&#xff09; ✅ 总结 &am…...

【ts】for in对象时,ts如何正确获取对应的属性值

第一种&#xff1a;for…in keyof&#xff1a;适合需要遍历对象属性键并动态访问值的场景。 keyof typeof obj是ts的类型操作符&#xff0c;用于获取对象obj的所有属性键的联合类型&#xff08;“name” | “age” | “city”&#xff09;通过obj[key keyof typeof obj]&…...

软考 系统架构设计师系列知识点之杂项集萃(55)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;54&#xff09; 第89题 某软件公司欲开发一个Windows平台上的公告板系统。在明确用户需求后&#xff0c;该公司的架构师决定采用Command模式实现该系统的界面显示部分&#xff0c;并设计UML类图如…...

绑定 SSH key(macos)

在 macOS 上绑定 Gitee 或 GitHub 的 SSH Key&#xff0c;通常分为以下几步操作&#xff0c;包括生成 SSH key、添加到 ssh-agent&#xff0c;并配置到 Gitee 或 GitHub 平台。 1. 检查是否已有 SSH Key ls -al ~/.ssh 看看是否已有 id_rsa 或 id_ed25519 等文件。如果没有就…...

PyTorch API 6 - 编译、fft、fx、函数转换、调试、符号追踪

文章目录 torch.compiler延伸阅读 torch.fft快速傅里叶变换辅助函数 torch.func什么是可组合的函数变换&#xff1f;为什么需要可组合的函数变换&#xff1f;延伸阅读 torch.futurestorch.fx概述编写转换函数图结构快速入门图操作直接操作计算图使用 replace_pattern() 进行子图…...

Unreal 从入门到精通之VR常用操作

文章目录 前言1.如何设置VRPawn视角的位置。2.如何播放视频3.如何播放VR全景视频。4.如何打开和关闭VR模式。前言 我们使用Unreal5 开发VR 项目的时候,会遇到很多常见问题。 比如: 1.如何设置VRPawn视角的位置。 2.如何播放视频。 3.如何播放VR全景视频。 4.如何打开和关闭V…...

Dify使用总结

最近完成了一个Dify的项目简单进行总结下搭建服务按照官方文档操作就行就不写了。 进入首页之后由以下组成&#xff1a; 探索、工作室、知识库、工具 探索&#xff1a; 可以展示自己创建的所有应用&#xff0c;一个应用就是一个APP&#xff0c;可以进行测试使用 工作室包含…...

事务连接池

一、事务概述 &#xff08;一&#xff09;事务的定义 事务是数据库提供的一种特性&#xff0c;用于确保数据操作的完整性和一致性。事务将多个数据操作组合成一个逻辑单元&#xff0c;这些操作要么全部成功&#xff0c;要么全部失败。 &#xff08;二&#xff09;事务的特性…...