【Rust】005-Rust 结构体

2024-09-02 23:28
文章标签 rust 结构 005

本文主要是介绍【Rust】005-Rust 结构体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【Rust】005-Rust 结构体

文章目录

  • 【Rust】005-Rust 结构体
  • 一、基本使用
    • 1、代码示例
    • 2、说明
    • 3、简化的结构体实例的创建写法
      • 简化前
      • 简化后
      • 说明
    • 4、使用新实例更新字段
  • 二、元组结构体
    • 1、代码示例
    • 2、说明
    • 3、使用场景案例
      • (1)类型安全的标识符
      • (2)封装简单的值
      • (3)实现自定义行为
      • (4)用于单元测试
  • 三、单元结构体
    • 1、代码示例
    • 2、说明
    • 3、单元结构体实例
      • 代码
      • 说明
    • 4、Rust 单元结构体与 Java 接口的比较
    • 5、更多使用场景案例
      • (1)类型标记
      • (2)特征实现
      • (3)配置选项
      • (4)单元测试标记
      • (5)零大小类型(ZST)
  • 四、函数与方法
    • 1、定义方法
    • 2、调用方法
    • 3、所有权转移
      • (1) `self`
      • (2) `&self`
      • (3)`&mut self`
    • 4、关联函数
      • 基本使用
      • 使用场景案例
      • Rust 关联函数与 Java 静态方法的比较
  • 五、面向对象三个特性案例
    • 1、代码示例
    • 2、代码详解

一、基本使用

1、代码示例

// 定义一个名为Person的结构体
struct Person {name: String,age: u32,email: String,
}fn main() {// 使用mut关键字创建一个可变的Person实例let mut person = Person {name: String::from("Alice"),age: 30,email: String::from("alice@example.com"),};// 更新字段的值person.age = 31;person.email = String::from("alice_new@example.com");// 打印更新后的字段println!("Updated Age: {}", person.age);println!("Updated Email: {}", person.email);
}

2、说明

  1. 结构体定义

    • 使用struct关键字定义一个结构体,后跟结构体的名称(如Person)。
    • 在大括号内定义结构体的字段,每个字段都有名称和类型。
  2. 字段类型

    • 字段类型可以是任意有效的Rust数据类型,包括基本类型(如u32)和复杂类型(如String)。
  3. 实例化结构体

    • 使用结构体名称加上大括号来创建结构体的实例。
    • 在实例化时,必须为每个字段提供初始值
    • 初始化时的字段顺序不需要要和结构体定义时保持一致。
  4. 访问字段

    • 使用点号(.)语法来访问结构体实例的字段。
  5. 更新字段

    • 使用let mut来创建一个可变的结构体实例。只有在实例是可变的情况下,才能更新其字段。
    • 使用点号(.)语法直接更新字段的值,例如person.age = 31;

3、简化的结构体实例的创建写法

简化前

fn create_point(x: f64, y: f64) -> Point {Point {x: x,y: y,}
}

简化后

fn create_point(x: f64, y: f64) -> Point {Point {x,y,}
}

说明

字段名和初始化使用的变量名刚好相同,可以作如上简写!


4、使用新实例更新字段

如果结构体实例是不可变的,可以通过创建一个新实例来“更新”字段:

// 定义一个名为Person的结构体
struct Person {name: String,age: u32,email: String,
}fn main() {let person = Person {name: String::from("Alice"),age: 30,email: String::from("alice@example.com"),};// 创建一个新实例,并更新某些字段let updated_person = Person {age: 31,  // 更新年龄email: String::from("alice_new@example.com"), // 更新邮箱..person // 使用其他未改变的字段};// 打印更新后的字段println!("Updated Age: {}", updated_person.age);println!("Updated Email: {}", updated_person.email);
}

使用结构体更新语法:

  • 在创建新实例时,可以使用..语法来复制其他未改变的字段。这种方法称为结构体更新语法。
  • 例如,..person表示使用person中未显式更新的字段的值。

二、元组结构体

在Rust中,元组结构体是一种特殊的结构体形式,它结合了元组和结构体的特性。元组结构体类似于普通的结构体,但它没有字段名称只有字段类型。这种结构体更像是带标签的元组,通常用于需要对某些数据进行简单封装不需要命名每个字段的场景。

1、代码示例

下面是一个简单的元组结构体的定义和使用示例:

// 定义一个元组结构体Color
struct Color(u8, u8, u8);// 定义一个元组结构体Point
struct Point(f64, f64, f64);fn main() {// 创建Color结构体的实例let black = Color(0, 0, 0);let white = Color(255, 255, 255);// 创建Point结构体的实例let origin = Point(0.0, 0.0, 0.0);let point = Point(1.0, 2.0, 3.0);// 访问元组结构体的字段println!("Black color: ({}, {}, {})", black.0, black.1, black.2);println!("White color: ({}, {}, {})", white.0, white.1, white.2);println!("Origin point: ({}, {}, {})", origin.0, origin.1, origin.2);println!("Point: ({}, {}, {})", point.0, point.1, point.2);
}

2、说明

  1. 定义元组结构体

    • 使用struct关键字定义元组结构体,后跟结构体名称及字段类型列表。
    • 例如,struct Color(u8, u8, u8);定义了一个Color结构体,包含三个u8类型的字段。
  2. 实例化元组结构体

    • 创建实例时,只需提供字段值,不需要指定字段名称。
    • 例如,let black = Color(0, 0, 0);创建了一个Color实例。
  3. 访问字段

    • 使用索引访问元组结构体的字段,类似于访问元组的元素。
    • 例如,black.0访问black实例的第一个字段。

元组结构体非常适合用于对简单数据进行分组和标签化,而不需要过多的命名复杂性。它们在一些简单的封装场景中可以提供很好的可读性和便利性。


3、使用场景案例

(1)类型安全的标识符

// 定义两个元组结构体,用于区分不同类型的ID
struct UserId(u32);
struct OrderId(u32);// 打印用户ID
fn print_user_id(id: UserId) {println!("User ID: {}", id.0);
}// 打印订单ID
fn print_order_id(id: OrderId) {println!("Order ID: {}", id.0);
}fn main() {let user_id = UserId(1);let order_id = OrderId(2);print_user_id(user_id);// print_user_id(order_id); // 这行会导致编译错误,确保类型安全
}

(2)封装简单的值

// 定义两个元组结构体,用于表示米和千克
struct Meters(f64);
struct Kilograms(f64);// 计算BMI(身体质量指数)
fn calculate_bmi(weight: Kilograms, height: Meters) -> f64 {weight.0 / (height.0 * height.0)
}fn main() {let weight = Kilograms(70.0); // 体重70千克let height = Meters(1.75);    // 身高1.75米let bmi = calculate_bmi(weight, height);println!("BMI: {:.2}", bmi); // 输出BMI值
}

(3)实现自定义行为

use std::ops::Add;// 定义一个元组结构体,用于表示二维向量
struct Vector2D(f64, f64);// 为Vector2D实现Add特征,实现向量相加功能
impl Add for Vector2D {type Output = Self;fn add(self, other: Self) -> Self {Vector2D(self.0 + other.0, self.1 + other.1)}
}fn main() {let vector1 = Vector2D(1.0, 2.0); // 向量1let vector2 = Vector2D(3.0, 4.0); // 向量2let result = vector1 + vector2; // 向量相加println!("Resulting Vector: ({}, {})", result.0, result.1);
}

(4)用于单元测试

// 定义一个元组结构体,用于测试数据
#[derive(Debug)]
struct TestData(i32, i32);// 一个简单的加法函数
fn add(a: i32, b: i32) -> i32 {a + b
}#[cfg(test)]
mod tests {use super::*;#[test]fn test_add() {let data = TestData(2, 3); // 测试数据assert_eq!(add(data.0, data.1), 5); // 验证加法结果}
}

三、单元结构体

单元结构体是一种特殊的结构体形式,它没有任何字段。单元结构体在Rust中类似于空的元组(),通常用于需要类型但不需要存储数据的场景。它们可以用于实现某些特征,或者作为标记类型来区分不同的状态或行为。

1、代码示例

// 定义一个单元结构体
struct UnitStruct;// 实现一个特征用于单元结构体
trait MyTrait {fn do_something(&self);
}// 为单元结构体实现特征
impl MyTrait for UnitStruct {fn do_something(&self) {println!("UnitStruct is doing something!");}
}fn main() {// 创建一个单元结构体的实例let unit = UnitStruct;// 调用实现的特征方法unit.do_something();
}

2、说明

  1. 定义单元结构体

    • 单元结构体的定义形式非常简单,只需struct关键字后跟结构体名称,无需大括号和字段。
    • 例如,struct UnitStruct;定义了一个名为UnitStruct的单元结构体。
  2. 实现特征

    • 单元结构体可以实现特征,与其它结构体或枚举没有区别。
    • 在示例中,我们为UnitStruct实现了一个名为MyTrait的特征,并定义了do_something方法。
  3. 实例化和使用

    • 单元结构体的实例化不需要任何参数,直接使用其名称即可创建一个实例。
    • 例如,let unit = UnitStruct;创建了一个UnitStruct实例。
    • 可以使用实例调用实现的特征方法。

单元结构体在Rust中虽然没有数据存储能力,但由于它们是合法的类型,因此可以在需要类型标识的地方使用。它们常用于实现特征、标记类型或作为状态标识符。


3、单元结构体实例

代码

// 定义单元结构体用于表示日志级别
struct Info;
struct Warning;
struct Error;// 定义一个特征用于日志行为
trait Logger {fn log(&self, message: &str);
}// 为每个日志级别实现Logger特征
impl Logger for Info {fn log(&self, message: &str) {println!("[INFO]: {}", message);}
}impl Logger for Warning {fn log(&self, message: &str) {println!("[WARNING]: {}", message);}
}impl Logger for Error {fn log(&self, message: &str) {println!("[ERROR]: {}", message);}
}fn main() {// 创建不同日志级别的实例let info_logger = Info;let warning_logger = Warning;let error_logger = Error;// 使用不同的日志级别输出消息info_logger.log("This is an informational message.");warning_logger.log("This is a warning message.");error_logger.log("This is an error message.");
}

说明

  1. 定义单元结构体
    • 定义了三个单元结构体:InfoWarningError,分别用于表示不同的日志级别。
  2. 定义特征
    • 定义了一个Logger特征,其中包含一个log方法,用于输出日志消息。
  3. 实现特征
    • 为每个单元结构体实现Logger特征,定义各自的log方法,输出对应的日志级别前缀。
  4. 实例化和使用
    • main函数中,创建了三个单元结构体的实例。
    • 调用各自的log方法,输出带有不同日志级别前缀的消息。

4、Rust 单元结构体与 Java 接口的比较

特性/功能Rust 特征(Traits)Java 接口(Interfaces)
定义行为定义一组方法签名,无需实现具体行为定义一组方法签名,无需实现具体行为
默认实现支持方法的默认实现从Java 8开始支持默认方法实现
多重实现一个类型可以实现多个特征一个类可以实现多个接口
泛型支持强大的泛型支持,可通过特征约束限制类型行为支持泛型类,但不如Rust特征灵活
静态分发支持(通过泛型),编译时确定调用不支持,通常是动态分发
动态分发支持(通过特征对象),运行时确定调用支持,通过虚方法表实现
关联类型支持定义关联类型,与实现类型相关不支持关联类型
实现细节可以在实现中隐藏实现细节实现类需提供所有接口方法的具体实现
继承与扩展特征可以继承其他特征接口可以继承其他接口

5、更多使用场景案例

单元结构体在Rust中虽然没有字段,但由于其类型标识的特性,可以在多种场景中发挥重要作用。以下是一些有趣的使用场景:

(1)类型标记

单元结构体常用于标记类型或状态,这对于编译时类型安全和逻辑分离非常有用。例如,可以用来标记不同的状态,避免混淆。

struct Connected;
struct Disconnected;struct NetworkState<T> {state: T,
}fn main() {let connected = NetworkState { state: Connected };let disconnected = NetworkState { state: Disconnected };// 根据不同的状态执行不同的逻辑
}

(2)特征实现

单元结构体可以实现特征,用于定义不依赖于数据的行为。这样可以为不同的类型提供相同的接口。

struct Logger;trait Log {fn log(&self, message: &str);
}impl Log for Logger {fn log(&self, message: &str) {println!("Log: {}", message);}
}fn main() {let logger = Logger;logger.log("This is a log message.");
}

(3)配置选项

单元结构体可以用于标记配置选项,帮助定义一组静态的配置参数。

struct DebugMode;
struct ReleaseMode;struct Config<T> {mode: T,
}fn main() {let debug_config = Config { mode: DebugMode };let release_config = Config { mode: ReleaseMode };// 根据不同的配置执行不同的逻辑
}

(4)单元测试标记

在测试中,单元结构体可以用于标记测试用例或测试环境,帮助组织和管理测试逻辑。

#[cfg(test)]
mod tests {struct TestEnv;#[test]fn test_example() {let _env = TestEnv;// 使用TestEnv执行测试逻辑assert_eq!(1 + 1, 2);}
}

(5)零大小类型(ZST)

由于单元结构体没有字段,它们是零大小类型(Zero-Sized Types),在内存中不占用空间。这使得它们在需要占位符的场合非常高效。

struct Placeholder;fn main() {let _placeholder = Placeholder;// 作为占位符使用,不占用内存
}

四、函数与方法

在前面的章节中,我们已经学过了什么是函数。方法和函数有些类似的地方:它们都由关键字fn定义,都有一个名字,都可以有参数和返回值。方法与函数的不同之处在于,方法是定义在结构体的上下文中,第一个参数永远是self,用来表示方法被调用的结构体实例。

注:方法也可以用在枚举类型和特征中,这两点会在后面的章节介绍。

1、定义方法

// 定义一个结构体 Rectangle,用于表示矩形
struct Rectangle {width: u32,  // 矩形的宽度,类型为 u32height: u32, // 矩形的高度,类型为 u32
}// 为结构体 Rectangle 实现方法
impl Rectangle {// 定义一个方法 area,用于计算矩形的面积// &self 表示该方法是针对结构体实例的,是self: &Self的简写fn area(&self) -> u32 {// 返回矩形的面积,计算公式为宽度乘以高度self.width * self.height}
}

2、调用方法

// 定义一个结构体 Rectangle,用于表示矩形
struct Rectangle {width: u32,  // 矩形的宽度,类型为 u32height: u32, // 矩形的高度,类型为 u32
}// 为结构体 Rectangle 实现方法
impl Rectangle {// 定义一个方法 area,用于计算矩形的面积// &self 表示该方法是针对结构体实例的,是self: &Self的简写fn area(&self) -> u32 {// 返回矩形的面积,计算公式为宽度乘以高度self.width * self.height}
}fn main() {// 创建结构体实例let r = Rectangle {width: 10,height: 10};// 调用实例的方法let area = r.area();// 打印计算结果:The area of the rectangle is 100println!("The area of the rectangle is {}", area);
}

3、所有权转移

定义方法的时候第一个参数self有三种类型:self,&self&mut self

在 Rust 中,self&self&mut self 是定义结构体方法时常用的三种接收者类型,它们的区别主要在于对结构体实例的访问权限和使用场景。下面我们分别对这三种类型进行说明,并给出相应的代码示例。

(1) self

  • 说明self 表示方法会获取结构体实例的所有权。调用该方法后,原来的实例不再有效,因为所有权已经转移给方法。
  • 使用场景:当方法需要在内部转移或消费结构体实例时使用。
struct Rectangle {width: u32,height: u32,
}impl Rectangle {fn consume(self) {println!("Consuming a rectangle with width: {} and height: {}", self.width, self.height);// 此处可以进行一些需要消耗实例的操作}
}fn main() {let rect = Rectangle { width: 10, height: 20 };rect.consume(); // 此时 rect 的所有权被转移,rect 已经无效// println!("{:?}", rect); // 编译错误,rect 已经无效
}

(2) &self

  • 说明&self 表示方法通过不可变引用访问结构体实例。调用该方法不会改变实例,也不会转移所有权
  • 使用场景:当方法只需要读取数据,不需要修改结构体实例时使用。
struct Rectangle {width: u32,height: u32,
}impl Rectangle {fn area(&self) -> u32 {self.width * self.height}
}fn main() {let rect = Rectangle { width: 10, height: 20 };let area = rect.area();println!("The area is {}", area); // rect 仍然有效
}

(3)&mut self

  • 说明&mut self 表示方法通过可变引用访问结构体实例。调用该方法可以修改实例
  • 使用场景:当方法需要修改结构体实例时使用。
struct Rectangle {width: u32,height: u32,
}impl Rectangle {fn double_size(&mut self) {self.width *= 2;self.height *= 2;}
}fn main() {let mut rect = Rectangle { width: 10, height: 20 };rect.double_size(); // 修改了 rect 的宽和高println!("New dimensions: width = {}, height = {}", rect.width, rect.height);
}

4、关联函数

基本使用

impl块中,除了可以定义方法,还可以定义函数。这些函数的第一个参数不是self,因此就不能像person.greet()这样来调用。又因为函数定义在了impl块中,我们认为这个函数和结构体关系密切,因此称它为关联函数。

impl Rectangle {fn new(w: u32, h: u32) -> Rectangle {Rectangle { width: w, height: h }}
}fn main() {let sq = Rectangle::new(3,3);
}

这里我们就创建了一个名为new的构造函数。注意这里使用new只是一个约定俗成的用法,并不是强制的规定。因为new不是一个方法,因此不能像方法那样使用.来调用。要调用这个new,需要像上例中一样使用::语法。


使用场景案例

好的,下面我将为每种使用场景提供一个实际的代码案例。

构造器函数

构造器函数通常用于创建和初始化结构体实例,new函数是一个常见的惯例。

struct Point {x: i32,y: i32,
}impl Point {// 构造器函数,用于创建一个新的Point实例fn new(x: i32, y: i32) -> Point {Point { x, y }}
}fn main() {let point = Point::new(10, 20);println!("Point: ({}, {})", point.x, point.y);
}

工厂模式

工厂模式允许根据不同的参数或条件创建不同类型的实例。

enum Shape {Circle(f64),   // 半径Square(f64),   // 边长
}impl Shape {// 工厂方法,根据类型创建不同的Shape实例fn create(shape_type: &str, size: f64) -> Option<Shape> {match shape_type {"circle" => Some(Shape::Circle(size)),"square" => Some(Shape::Square(size)),_ => None,}}
}fn main() {if let Some(circle) = Shape::create("circle", 5.0) {println!("Created a circle.");}if let Some(square) = Shape::create("square", 2.0) {println!("Created a square.");}
}

实用函数

实用函数提供一些不需要实例就可以执行的功能,如计算或转换。

struct MathUtils;impl MathUtils {// 计算两个数的最大公约数fn gcd(a: u32, b: u32) -> u32 {let mut x = a;let mut y = b;while y != 0 {let temp = y;y = x % y;x = temp;}x}
}fn main() {let result = MathUtils::gcd(48, 18);println!("The GCD is {}", result);
}

常量定义

通过关联函数实现一些常量值的获取或配置。

struct Config;impl Config {// 返回默认端口号fn default_port() -> u16 {8080}
}fn main() {let port = Config::default_port();println!("Default port is {}", port);
}

Rust 关联函数与 Java 静态方法的比较

特性/方面Rust 关联函数Java 静态方法
所属属于类型(impl块)属于类(class
调用方式使用TypeName::function_name()调用使用ClassName.methodName()调用
实例依赖不依赖于特定实例不依赖于特定实例
self/this引用self引用this引用
用途构造器、工厂方法、实用函数、常量定义工厂方法、实用函数、常量定义
访问限制可以访问类型的私有字段和方法可以访问类的私有静态字段和方法
多态支持不支持关联函数的多态(无继承)支持静态方法的多态(通过类继承)
泛型支持强大的泛型支持支持泛型,但较为有限
生命周期管理通过Rust的生命周期管理,确保安全由Java的垃圾回收机制管理
线程安全性通过Rust的借用检查和所有权系统保证安全通过Java的同步机制和并发工具保障安全

五、面向对象三个特性案例

1、代码示例

// 定义一个特征,表示可以计算面积的形状
trait Area {fn area(&self) -> f64;
}// 定义一个结构体表示矩形
struct Rectangle {width: f64,height: f64,
}// 为Rectangle实现Area特征
impl Area for Rectangle {fn area(&self) -> f64 {self.width * self.height}
}// 定义一个结构体表示圆形
struct Circle {radius: f64,
}// 为Circle实现Area特征
impl Area for Circle {fn area(&self) -> f64 {3.141592653589793 * self.radius * self.radius}
}// 定义一个结构体表示三角形
struct Triangle {base: f64,height: f64,
}// 为Triangle实现Area特征
impl Area for Triangle {fn area(&self) -> f64 {0.5 * self.base * self.height}
}// 使用特征对象进行多态
fn print_area(shape: &dyn Area) {println!("The area is {}", shape.area());
}fn main() {// 创建不同类型的形状let rectangle = Rectangle { width: 3.0, height: 4.0 };let circle = Circle { radius: 5.0 };let triangle = Triangle { base: 6.0, height: 7.0 };// 多态调用print_area(&rectangle);print_area(&circle);print_area(&triangle);
}

2、代码详解

  1. 封装
    • 结构体RectangleCircleTriangle都将其字段定义为私有,默认情况下,这些字段只能在定义它们的模块内访问。
    • 通过实现Area特征,提供了一个公开的方法area来计算面积。
  2. 继承
    • Rust不支持传统的类继承,但通过特征(trait)可以实现类似的行为共享。
    • 在这个例子中,RectangleCircleTriangle都实现了Area特征,表明它们都具有计算面积的能力。
  3. 多态
    • 函数print_area接受一个实现了Area特征的特征对象(&dyn Area),这允许它在运行时接受任何实现了Area特征的类型。
    • 这就实现了多态,函数可以处理不同类型的形状,而不需要知道它们的具体类型。

这篇关于【Rust】005-Rust 结构体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131370

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

【Rust练习】12.枚举

练习题来自:https://practice-zh.course.rs/compound-types/enum.html 1 // 修复错误enum Number {Zero,One,Two,}enum Number1 {Zero = 0,One,Two,}// C语言风格的枚举定义enum Number2 {Zero = 0.0,One = 1.0,Two = 2.0,}fn m

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

C语言程序设计(选择结构程序设计)

一、关系运算符和关系表达式 1.1关系运算符及其优先次序 ①<(小于) ②<=(小于或等于) ③>(大于) ④>=(大于或等于 ) ⑤==(等于) ⑥!=(不等于) 说明: 前4个优先级相同,后2个优先级相同,关系运算符的优先级低于算术运算符,关系运算符的优先级高于赋值运算符 1.2关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式,逻辑表达式,赋值表达式,字符

Science|癌症中三级淋巴结构的免疫调节作用与治疗潜力|顶刊精析·24-09-08

小罗碎碎念 Science文献精析 今天精析的这一篇综述,于2022-01-07发表于Science,主要讨论了癌症中的三级淋巴结构(Tertiary Lymphoid Structures, TLS)及其在肿瘤免疫反应中的作用。 作者类型作者姓名单位名称(中文)通讯作者介绍第一作者Ton N. Schumacher荷兰癌症研究所通讯作者之一通讯作者Daniela S. Thomm

第二十四章 rust中的运算符重载

注意 本系列文章已升级、转移至我的自建站点中,本章原文为:rust中的运算符重载 目录 注意一、前言二、基本使用三、常用运算符四、通用约束 一、前言 C/C++中有运算符重载这一概念,它的目的是让即使含不相干的内容也能通过我们自定义的方法进行运算符操作运算。 比如字符串本身是不能相加的,但由于C++中的String重载了运算符+,所以我们就可以将两个字符串进行相加、但实际

oracle11.2g递归查询(树形结构查询)

转自: 一 二 简单语法介绍 一、树型表结构:节点ID 上级ID 节点名称二、公式: select 节点ID,节点名称,levelfrom 表connect by prior 节点ID=上级节点IDstart with 上级节点ID=节点值 oracle官网解说 开发人员:SQL 递归: 在 Oracle Database 11g 第 2 版中查询层次结构数据的快速

Tomcat下载压缩包解压后应有如下文件结构

1、bin:存放启动和关闭Tomcat的命令的路径。 2、conf:存放Tomcat的配置,所有的Tomcat的配置都在该路径下设置。 3、lib:存放Tomcat服务器的核心类库(JAR文件),如果需要扩展Tomcat功能,也可将第三方类库复制到该路径下。 4、logs:这是一个空路径,该路径用于保存Tomcat每次运行后产生的日志。 5、temp:保存Web应用运行过程中生成的临时文件