Rust之结构体(二):结构体示例

Rust学习:通过例子学Rust 官方文档:通过例子学Rust的个人笔记,陆续学习中,大佬别喷 阅读详情

开发环境

  • Windows 10
  • Rust 1.57.0

 

   VS Code 1.63.2

 项目工程

这里继续沿用上次工程rust-demo

结构体示例

为了理解什么时候可能需要使用结构体,让我们编写一个程序来计算矩形的面积。我们将从单变量开始,然后重构程序,直到使用结构代替。

让我们用`cargo`创建一个名为`rectangles`的新的程序,它将以像素为单位指定矩形的宽度和高度,并计算矩形的面积。代码如下

fn main() {
    let width1 = 30;            // 宽度
    let height1 = 50;           // 高度

    println!(
        "The area of the rectangle is {} square pixels.",
        area(width1, height1)
    );
}

// 计算面积的接口
fn area(width: u32, height: u32) -> u32 {
    width * height
}

运行

cargo run

 尽管上述示例中可以通过调用每个维度的area函数计算出矩形的面积,但我们可以做得更好。宽度和高度是相互关联的,因为它们一起描述了一个矩形。

这个代码的问题在area的签名中很明显:

fn area(width: u32, height: u32) -> u32 {

面积函数area是用来计算一个矩形的面积的,但是我们写的这个函数有两个参数。这些参数是相关的,但在我们的程序中没有表示。将宽度和高度组合在一起将更易于阅读和管理。我们可以使用Tuple类型来重构上述代码。

使用Tuple重构

可以查看下述代码:

fn main() {
    let rect1 = (30, 50);           // 使用Tuple类型

    println!(
        "The area of the rectangle is {} square pixels.",
        area(rect1)
    );
}

fn area(dimensions: (u32, u32)) -> u32 {
    dimensions.0 * dimensions.1
}

在某种程度上,这段代码更好。tuple让我们添加一些结构,现在我们只传递一个参数。但是在另一种方式上,这个版本不太清楚:tuple没有命名它们的元素,因此我们的计算变得更加混乱,因为我们必须对元组的各个部分进行索引。

如果我们在计算面积时混合宽度和高度是没有关系的,但如果我们想在屏幕上绘制矩形,这就有关系了!我们必须记住,width是tuple的下标0而height是元组的下标1。如果有其他人在研究这段代码,他们也会发现这一点,并牢记于心。很容易忘记或混淆这些值并导致错误,因为我们没有在代码中表达数据的含义。

使用结构体进行重构:增加更多的意义

我们通过标记数据来使用结构体来增加意义。我们可以将正在使用的tuple转换为具有整体名称和部分名称的数据类型,如下所示:

// 定义Rectangle结构体
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() { 
   // 初始化结构体
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!(
        "The area of the rectangle is {} square pixels.",
        area(&rect1)
    );
}

fn area(rectangle: &Rectangle) -> u32 {
    rectangle.width * rectangle.height
}

在这里我们定义了一个结构体,并将其命名为Rectangle。在花括号内,我们定义了width和height字段,它们的类型都是u32。然后在main中,我们创建了一个特殊的矩形实例,它的宽度为30,高度为50。

我们的area函数现在定义了一个参数,我们将其命名为rectangle,它的类型是一个不可变的借用struct rectangle实例。正如之前的章节所提到的,我们想借用这个结构,而不是占有它。这样,main保留了它的所有权,并可以继续使用rect1,这就是我们在函数签名中使用&的原因以及我们调用函数的地方。

area函数访问Rectangle实例的width和height字段。我们对于area的函数签名现在确切地表达了我们的意思:计算矩形的面积,使用其width和height字段。这表示宽度和高度是相互关联的,它为值提供描述性的名称,而不是使用元组索引值0和1,这样就很清晰了。

使用派生特征添加有用的功能

当我们重新调试程序并看到它所有字段的值时,能够打印一个Rectangle的实例是很好的。如下示例:

struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {}", rect1);
}

编译运行

cargo run

println!宏可以执行多种格式,默认情况下,大括号告诉println!使用被称为Display的格式化:直接供终端用户使用的输出。到目前为止,我们所看到的基元类型在默认情况下实现了Display,因为只有一种方式可以向用户显示1或任何其他基元类型。但是对于结构,println!输出的格式应该不那么清晰,因为有更多的显示可能性:是否需要逗号?要打印花括号吗?是否应该显示所有字段?由于这种模糊性,Rust不会尝试猜测我们想要什么,结构也没有提供Display的实现。 

可以尝试`println!("rect1 is {:?}", rect1)`这种方式,输入说明符:?在花括号里告诉println!我们希望使用一种名为Debug的输出格式。Debug特性使我们能够以一种对开发人员有用的方式打印结构,这样我们在重新调试代码时就可以看到它的值。更改后的代码如下: 

struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {:?}", rect1);
}

编译运行

cargo run

 Rust确实包含了打印调试信息的功能,但是我们必须明确地选择,使该功能对我们的结构可用。为此,我们在结构体定义前添加外部属性`[derive(Debug)]`,代码如下所示:

// debug属性
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {:?}", rect1);
}

编译运行

cargo run

 好了!这不是最完美的输出,但它显示了这个实例的所有字段的值,这在调试期间肯定会有帮助。当我们有更大的结构体时,有更容易阅读的输出是很有用的。可以使用`{:#?}`代替`{:?}`,代码如下:

// debug属性
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {:#?}", rect1);
}

编译运行

cargo run

 使用Debug格式打印值的另一种方法是使用dbg!宏。dbg!宏获取表达式的所有权,输出dbg!宏调用与表达式的结果值一起发生在代码中,并返回值的所有权。调用dbg!宏打印到标准错误控制台流(stderr),而不是println!输出到标准输出控制台流(stdout)。这时代码如下:

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let scale = 2;
    let rect1 = Rectangle {
        width: dbg!(30 * scale),
        height: 50,
    };

    dbg!(&rect1);
}

 编译运行

cargo run

 我们可以看到第一个输出来自src/main.rs第489行,其中我们重新调试表达式30 * scale,其结果值为60(为整数实现的Debug格式是只打印它们的值)。dbg!在src/main.rs的493行输出了Rectangle结构体实例&rect1。这个输出使用了Rectangle类型的完美的调试格式。当试图弄清楚代码正在做什么时,dbg!宏非常有用。

除了Debug特性之外,Rust还提供了许多特性,可以与派生属性一起使用,这些派生属性可以为我们的自定义类型添加有用的行为。

area函数非常具体:它只计算矩形的面积。这将有助于把这个行为更紧密地联系到我们的Rectangle结构,因为它不会与任何其他类型工作。让我们看看如何通过将area函数转换为定义在Rectangle类型上的area方法来继续重构这段代码。

本章重点

  • 结构体使用
  • Debug模式
  • dbg!宏的使用
在Rust中使用torch------day1环境配置&Yolov8推理 我通过tch用Rust实现了对Yolov8的推理,并且最终输出结果与实际推理结果一致,很好的做到了精度对齐.不过这里面还是存在一点点小问题的,模型推理讲究的是推理时间与实时性要求,来看看在不同device下我推理时间的结果. 阅读详情

相关推荐

Rust实战:高效开发技巧

本文精选了基于Rust的各类实用编程示例,涵盖Web开发、系统编程、AI/ML、数据库操作等核心领域。主要内容包括:1)Web框架(Actix、Axum、Warp)的HTTP服务、WebSocket、中间件等实现;2)系统级开发如多线程同步(Mutex、通道)、操作系统组件(RedoxOS)和网络编程;3)人工智能领域的机器学习算法(KNN、线性回归)、深度学习框架集成和NLP处理(rust-bert);4)数据库操作(MySQL连接池、事务处理、binlog解析)以及与MySQL Workbench的配合

keny-大成的博客 1442

Unity RUST 逆向安全开发

本教程适合有一定基础的小白(会使用CE和易语言)购买此套教程后您将完全学会如何自行研发程序并且为游戏安全贡献一份力逆向安全开发设计 这是必不可少的一部分!  

【Rust结构体】Rust结构体详解:从基础到高级应用

结构体(struct)是Rust中一种自定义数据类型,它允许你将多个相关的值组合在一起,形成一个有意义的组。结构体是创建更复杂数据类型的基础,也是面向对象编程中"对象"概念的基石。 与元组类似,结构体的每个部分可以是不同类型。但与元组不同,结构体需要为每个部分命名,这使得数据访问更加清晰明确。

景天科技苑 5万+

Rust语言编程实例

求当m = 3, n = 6时的值。古典问题(兔子生崽):有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?现在有个需求,要求你打印一个有6个台阶的楼梯,同时从上向下数,在楼梯的第4节台阶有个足球。4、可得: m = (i + j) / 2, n = (i - j) / 2,i 和 j 要么都是偶数,要么都是奇数。3、设置: m + n = i,m - n = j,i * j =168,i 和 j 至少一个是偶数。

qq_52876054的博客 1474

rust-examples:Rust代码示例

生锈的例子 Rust代码示例

rust示例教程rust-by-example

该文档系统展示了rust编程语法示例,是rust学习者必备文档。

《Rust权威指南》第17章_Rust的面向对象编程特性_草稿

面向对象语言的特性 对象包含数据和行为 封装实现细节 作为类型系统和代码共享机制的继承 使用trait对象来存储不同类型的值 为共有行为定义一个trait 实现trait trait对象会执行动态派发 trait对象必须保证对象安全 实现一种面向对象的设计模式 定义Post并新建一个处于草稿状态下的新实例 存储文章内容的文本 确保草稿的可读内容为空 请求审批文章并改变其状态 添加approve方法来改变content的行为 状态模式的权衡取舍 将状态和行为编码成类型 post m.

weixin_50475073的博客 349

[pytorch]FixMatch代码详解(超详细)

FixMatch代码详解-训练过程参数数据产生构建模型训练参数设置weight decay(权值衰减)学习率衰减(learning rate decay)指数移动平均(EMA)model训练过程运行结果 上一篇大概讲了数据加载的过程,这一篇更进一步,分析一下训练是怎样进行的 上一篇链接: [pytorch]FixMatch代码详解-数据加载 参数 所有的参数我都默认使用作者给出的例子: python train.py --dataset cifar10 --num-labeled 4000 --arch w

qq_38736504的博客 1万+

Rust中结构体的定义和实例化

一旦定义了结构体后,为了使用它,通过为每个字段指定具体值来创建这个结构体的 实例。创建一个实例需要以结构体的名字开头,接着在大括号中使用 key: value 键-值对的形式提供字段,其中 key 是字段的名字,value 是需要存储在字段中的数据值。实例中字段的顺序不需要和它们在结构体中声明的顺序一致。换句话说,结构体的定义就像一个类型的通用模板,而实例则会在这个模板中放入特定数据来创建这个类型的值。 声明一个特定的用户: 为了从结构体中获取某个特定的值,可以使用点号。举个例子,想要用户的邮箱地址,可以用

write less , do more 6213

MIT6.824-lab2D-2022(日志压缩详细讲解)

从paper中去讲解,并实现关于lab2D的代码。

幸平的博客 6036

【DeepSeek+Office/WPS】智能办公新时代的全新利器

DeepSeek是一家专注于通用人工智能技术研发的中国科技公司,其核心产品DeepSeek-R1是一款开源的推理大模型,专注于复杂任务的高效处理,支持智能对话、文本生成、语义理解、计算推理、代码生成与补全等多种应用场景。作为国产、免费、开源且强大的AI平台,DeepSeek不仅致力于为终端用户提供高质量的智能服务,还为开发者提供了一整套完善的技术解决方案,帮助他们快速构建和部署自己的智能应用。

2303_77200324的博客 2791

【Rust】结构体示例与调试

本文通过一个计算矩形面积的程序,展示了如何从简单变量逐步重构到使用结构体,以提高代码的清晰度和可管理性。结构体是Rust中组织复杂数据的重要工具,能够显著提升代码的可读性和可维护性。函数中使用两个参数,缺乏参数之间的关联性,导致可读性差。结构体提供了更强的类型安全性,避免了参数顺序错误等问题。使用元组将宽度和高度组合为一个参数,增强数据的关联性。通过定义结构体为矩形增加语义,明确宽度和高度的关系。使用单独的变量定义矩形的宽度和高度,并通过。输出了计算过程中的中间值和最终的结构体值。

qq_61867911的博客 1232

【全部更新】2025金地杯E题山西省大学生数学建模思路代码文章教学:高速铁路牵引供电系统能耗优化

问题四将列车的运行速度与发车时间同时作为优化变量,建立联合优化模型,目标是在考虑电价机制和调度均衡性的前提下,使牵引供电系统一天内的总电费支出最小。问题三在考虑分时电价机制的基础上,基于遗传算法优化列车速度组合,使牵引供电系统一天内的总电费支出最小。然而,在实际运营中,不同时段的电价差异显著,合理安排列车的运行时间与运行速度,可有效降低系统的总电费支出。本研究聚焦于高速铁路牵引供电系统的能耗与电费优化问题,针对列车运行速度、发车时间与分时电价的综合影响,提出一系列数学模型,以实现系统能耗与电费的最小化。

xb459149247的博客 5289

Rust 数据类型 之 结构体(Struct)

结构体(Struct)是一种自定义数据类型,允许将多个相关的值组合在一起,形成一个更复杂的数据结构。结构体被广泛应用于组织和管理数据,具有灵活性和强大的表达能力。在Rust中,定义和声明结构体的语法如下: struct Name { field1: Type1, field2: Type2, // ... fieldN: TypeN, }

汉阳Hann's Home 6万+

基于Keil软件实现OLED显示(江协科技HAL库)

没有HAL库的OLED驱动文件,可以看过来

2401_82728381的博客 1453

UNet改进(24):注意力机制-从基础原理到高级融合策略

本文系统探讨了如何通过引入各类注意力机制增强UNet在医学图像分割中的性能。文章分为基础篇、进阶篇和高级篇三个层级:基础篇介绍了时序注意力、可变形注意力、分层注意力等8种基础机制;进阶篇提出了5种混合注意力设计;高级篇则探讨了全局+局部+多尺度等复杂组合机制。实验表明,这些注意力模块在心脏MRI、肺部感染等任务中能提升2-15%的分割精度。文章还提供了硬件适配建议和完整实现代码,为研究者提供了全面的技术参考。未来方向包括NAS优化、量子注意力等前沿探索,为UNet在医疗影像等领域的应用革新提供了理论指导。

2501_91516851的博客 765

Rust 语言中的结构体

结构体和我们之前论过的元组类似,它们都包含多个相关的值。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。定义结构体,需要使用struct关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,我们称为字段fieldage: u64,

专注于大数据方向,区块链,前后端,数据可视化,人工智能等领域 2396

YOLO系列算法改进 | C3k2改进篇 | 融合DFRL双融合注意力接收层 | 轻量化与全局感受野双突破,适应高分辨率航拍与密集小目标检测场景 | CVPR 2026

YOLO系列算法改进 | C3k2改进篇 | 融合DFRL双融合注意力接收层 | 轻量化与全局感受野双突破,适应高分辨率航拍与密集小目标检测场景 | CVPR 2026 (以YOLO26最新目标检测模型为基础,利用C3k2_DFRL创新模块进行改进)

2502_91881744的博客 233

rust结构体示例程序

area 函数访问 Rectangle 实例的 width 和 height 字段(注意,访问对结构体的引用的字段不会移动字段的所有权,这就是为什么你经常看到对结构体的引用)。area 的函数签名现在明确的阐述了我们的意图:使用 Rectangle 的 width 和 height 字段,计算 Rectangle 的面积。在第 14 行 的 dbg!我们希望借用结构体而不是获取它的所有权,这样 main 函数就可以保持 rect1 的所有权并继续使用它,所以这就是为什么在函数签名和调用的地方会有 &。

hello.reader 1020

C语言使用开源库libusb进行USB设备操作

https://libusb.info/libusb is a C library that provides generic access to USB devices. It is intended to be used by developers to facilitate the production of applications that communicate with USB hardware. It is portable: Using a single cross-platform AP

m0_60352504的博客 1554

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【Rust】005-Rust 结构体

/ 定义一个元组结构体,用于表示二维向量// 为Vector2D实现Add特征,实现向量相加功能// 向量1// 向量2// 向量相加println!// 定义一个结构体 Rectangle,用于表示矩形width: u32, // 矩形的宽度,类型为 u32height: u32, // 矩形的高度,类型为 u32// 为结构体 Rectangle 实现方法// 定义一个方法 area,用于计算矩形的面积。

訾博(ZiBo)的博客 1341

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Rust-结构体

我们定义一个结构体Rectangle​ ,这个结构体表示的是一个矩形,它有着 width 和 height 两个元素(字段)。我们现在要给这个结构体专门定义一个“方法”,用以计算矩形的面积。当我们为一个给定的结构体定义方法时,需要添加impl​关键字,也就是在impl块​中编写结构体的一些方法。另外,一个结构体可以有多个impl块​存在。在下面的代码中,我们给Rectangle​ 结构体上成功定义了area​ 方法,用来计算矩形的面积。

日拱一卒无有尽,功不唐捐终入海 1589

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

详解Rust结构体struct用法

Rust的结构体(struct)是一种自定义的数据类型,允许开发者命名和包装多个相关的值,以形成有意义的数据组合。在Rust中结构体不仅用于数据组织,还密切结合了Rust的内存安全性和所有权模型特性,在开发系统编程过程中很有用。

yang1fei2的博客 1836

【Rust】结构体

结构体和元组类似,它们都包含多个相关的值。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。定义结构体,需要使用struct关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,称为字段。一旦定义了结构体后,为了使用它,通过为每个字段指定具体值来创建这个结构体的实例。

m0_72516377的博客 1377

rust-结构体使用示例

area 函数访问 Rectangle 实例中的 width 和 height 字段(注意,对借用 struct 实例字段进行访问不会移动字段值,因此经常看到对 struct 的借用)。这表明宽高彼此关联,并且比起直接按索引访问 tuple 元素(如 .0、.1),这种方式提供了描述性的名称,有助于提升代码可读性,这是一次胜利。虽然不是最漂亮的输出,但它显示了实例所有字段的值,这在调试时非常有帮助。但另一方面,这个版本不够直观,因为元组元素没有名字,我们必须通过索引访问各部分,使得计算过程不那么明显。

qq_29372275的博客 827

Rust结构体

结构体和元组类似,它们都包含多个相关的值。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。定义结构体,需要使用 struct 关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,我们称为 字段(field)。一旦定义了结构体后,为了使用它,通过为每个字段指定具体值来创建这个结构体的实例。

hello.reader 1093
上一篇: Rust之结构体(一):定义和实例化结构体
下一篇: Rust之结构体(三):方法
枫★曦
博客等级 码龄19年 251粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值