结构体

// 如何定义结构体
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
// 如何使用结构体
let user = User {
active: true,
username: String::from("someusername123"),
email: String::from("someone@example.com"),
sign_in_count: 1,
}
// 解构
// 这里有个需要注意的是,如果某个类型没有实现Copy trait
// 那么就会传递所有权,比如这里的email,所以在定义完user2以后,user变量就不能再使用了
// 如果我们额外传入了email,那么user就还能使用
// 另一个问题:结构的位置会影响最后的值吗?就像js的对象结构,我们可以在下面覆盖掉上面解构对象的某些属性
// 在Rust中,结构(destructuring)不是用来“覆盖”值的,而是用来“重组”已存在的值到一个新的变量。这跟JavaScript的对象解构赋值不同,后者允许你在解构的同时覆盖之前对象的属性。
/**
好的,想象一下你有一个玩具箱子,里面有很多玩具。现在你想要一个新的箱子,而且你想把除了最爱的小黄鸭之外的所有玩具都放进新箱子里。在Rust中,我们可以用一个特殊的魔法词“..”,告诉大人我们想这么做。
所以我们对大人说:“请把我的所有玩具,除了小黄鸭,都移到新的箱子里去。”大人就会帮你做这件事。但是一旦玩具移到了新箱子里,你就不能再从旧箱子里拿玩具了,因为它们已经不在那里了。这就像当你把玩具借给朋友后,你就不能再玩那些借出去的玩具了。
而且,你不能像在画画时那样,先画一个太阳,然后又在上面画一个大风筝盖住太阳。在Rust里,一旦你把玩具放到了新箱子,你就决定好了谁去了新箱子,不能改变主意了。
这样的魔法规则帮助确保你的玩具箱子井井有条,每个玩具都知道它应该在哪个箱子里,就像确保你的房间整洁一样。这样你就不会弄丢玩具,也能更容易找到想玩的玩具。
*/
let user2 = User {
username: String::from("hahaha"),
...user
} // rust的整个结构体实例都必须是可变的,才能修改其中的属性,rust不允许只有某些属性是可变的 // build_user 函数返回的User实例,是可变的吗
/**
在Rust中,可变性是由变量的绑定决定的,而不是由函数返回的值决定的。
这意味着,当你的build_user函数返回一个User实例时,它返回的是一个不可变的User实例。
如果你想要修改这个User,你需要在使用它的地方将它绑定到一个可变变量上。
*/
fn build_user(email: String, username: String) -> User {
User {
active: true,
username: username,
email: email,
sign_in_count: 1,
}
}

rust的可不可变是针对变量而不是值的吗?

正是如此!在Rust的世界里,可变性(mutability)是关于变量绑定,而不是值本身。想象一下,你的玩具可以放在两种不同的箱子里:一个是用胶带封死的箱子(不可变的),另一个是可以随时打开加东西的箱子(可变的)。玩具(值)本身没变,但根据你放它的箱子的类型,你可能可以改变箱子里的玩具集合。

所以,在Rust中,当你声明一个变量时,你可以选择它是不是mut的,就是选择用哪种箱子。一旦你决定了,只有mut箱子里的玩具(值)才能被换掉或者修改。如果你试图改变一个用胶带封死的箱子里的玩具,Rust会阻止你,确保你不会意外地弄乱你的玩具集合。这个规则是Rust确保程序安全的方式之一,避免了数据在你不知情的情况下被更改。

这样的设计让Rust程序的行为变得非常可预测,并且减少了程序中出现错误的机会。而且,这还帮助Rust管理内存,因为它可以确切地知道何时某个值不再被需要,以及何时它可以被安全地回收或重新使用。

元组结构体

// 注意,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);
}

没有任何字段的类单元结构体

没有任何字段的类单元结构体有什么用呢?

好比是小朋友的想象游戏,有时候你会拿个香蕉当电话玩,对吧?虽然它就是个香蕉,但在你的游戏里它就变成了电话。在Rust的世界里,一个没有任何字段的结构体就像是那个香蕉电话,它本身没啥用,但你给它赋予了意义。

就像你可以想象香蕉是电话一样,程序员有时需要一些东西来代表某些特别的事情,即使那个东西本身什么都没有。比如说,我们可能有一个空的结构体来表示游戏中的一个事件,它本身不保存任何信息,但它的存在就代表了某个事件发生了。

还有,就像你玩耍时可能会用一个看不见的"盒子"来装你想象中的宝贝一样,程序员也可能会用这种结构体来做出某些选择。例如,它们可以用来打开或关闭软件的某些功能,就像是开关一样。

另外,这种结构体也像是游戏规则里的“它”,比如“你是它”游戏中的“它”。它代表了一个标记或者一个特定的角色,即使它自己没有任何东西。

所以,即使是空空如也的结构体,在Rust这个大型游戏中也有自己的角色和用途。这就是它们的魔法之处!

让我们来看一个Rust中的代码例子,这个例子里我们将使用一个没有任何字段的结构体来做一些有趣的事情。想象一下,我们有一个游戏,游戏里有一些特殊的时刻,比如“游戏开始”或“游戏结束”。我们可以用不同的结构体来代表这些时刻,哪怕这些结构体里面什么都没有!

这里有一个小小的代码片段:

// 定义一个没有字段的结构体,叫做 `GameEvent`。
struct GameStart; // 游戏开始事件
struct GameEnd; // 游戏结束事件 // 我们可以定义一个函数来处理游戏事件。
// 注意这个函数如何接受不同的事件结构体作为参数。
fn process_game_event(event: impl GameEventTrait) {
// 在这个函数里,我们可以根据事件的类型来做不同的事情。
event.print_details();
} // 让我们为这个结构体实现一个Trait,这个Trait允许我们打印出事件的细节。
trait GameEventTrait {
fn print_details(&self);
} // 实现 'GameStart' 结构体的 'GameEventTrait'。
impl GameEventTrait for GameStart {
fn print_details(&self) {
println!("The game has started!");
}
} // 实现 'GameEnd' 结构体的 'GameEventTrait'。
impl GameEventTrait for GameEnd {
fn print_details(&self) {
println!("The game has ended!");
}
} // 现在我们可以创建这些事件的实例并处理它们。
let start = GameStart;
let end = GameEnd; // 处理这些事件
process_game_event(start);
process_game_event(end);

在这个例子中,我们定义了两个没有任何字段的结构体:GameStartGameEnd。它们都实现了一个叫做 GameEventTrait 的trait,这个trait有一个方法 print_details,用于输出一个关于事件的消息。

然后我们有一个 process_game_event 函数,它接受任何实现了 GameEventTrait 的类型的实例。这意味着我们可以传入 GameStartGameEnd 的实例。

当我们调用这个函数并传入 GameStartGameEnd 的实例时,它会打印出相应的开始或结束游戏的消息。

这样的结构体很适合用于事件处理、状态机、消息传递等场景,在这些场景中,标记或者控制流的存在比持有数据更重要。

rust程序设计(3)结构体相关概念和疑问的更多相关文章

  1. C++程序设计之结构体,共用体,枚举和typedef

    [1]结构体的基本功 注意结构体里面可以有很多东西,可以结构体里面包含结构体 #include<iostream> using namespace std; struct Date { i ...

  2. Rust中的结构体及方法语法

    这个可以和类作比较,或是go当中的方法比较. #[derive(Debug)] struct Rectangle { width: u32, height: u32, } impl Rectangle ...

  3. C学习笔记(1)-结构体、预处理与多文件结构程序设计

    一.结构体的定义与使用 #include <stdio.h> //定义结构体(类似模板) typedef struct { char name[50]; int age; char add ...

  4. rust结构体

    //Rust 并不允许只将某个字段标记为可变 struct User { email: String, name:String, age:i32, sex:String, active:bool, } ...

  5. 计算机二级-C语言-程序设计题-190112记录-结构体的遍历和结构体的数据的交换处理,文件的操作。

    //程序设计题:学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun,它的功能是:把分数低的学生数据放在b所指的数组中,注意:分数最低的学生可能不止一个,函数返回 ...

  6. 读书笔记——Windows环境下32位汇编语言程序设计(13)关于EXCEPTION_DEBUG_INFO结构体

    在动手自己尝试编写书上第13章的例子Patch3时,遇到了一个结构体EXCEPTION_DEBUG_INFO. 这个结构体在MASM的windows.inc中的定义和MSDN中的定义不一样. (我使用 ...

  7. 全国计算机等级考试二级教程-C语言程序设计_第14章_结构体、共用体和用户定义类型

    函数的返回值是结构体类型 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> struct ...

  8. c语言程序设计案例教程(第2版)笔记(三)—变量、结构体

    零散知识点: 变量        :C语言中,每个变量必须先定义后引用.所谓变量存在是指系统为这个变量分配一块存储空间,此时对变量的操作,就是对变量所对应的存储空间中存放的数据进行操作.人们将变量占据 ...

  9. C语言程序设计(十二) 结构体和共用体

    第十二章 结构体和共用体 当需要表示复杂对象时,仅使用几个基本数据类型显然是不够的 根本的解决方法是允许用户自定义数据类型 构造数据类型(复合数据类型)允许用户根据实际需要利用已有的基本数据类型来构造 ...

  10. Go语言规格说明书 之 结构体类型(Struct types)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

随机推荐

  1. [爬虫]1.2.2 CSS选择器

    CSS (Cascading Style Sheets) 是一种样式表语言,用于描述HTML元素的样式.CSS选择器是CSS规则的一部分,它决定了CSS规则应用于哪些元素.在网络爬虫的开发中,我们经常 ...

  2. 《深入理解Java虚拟机》读书笔记:HotSpot虚拟机对象探秘

    基于实用优先的原则,以常用的虚拟机HotSpot和常用的内存区域Java堆为例,深入探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全过程.以下是本节内容的脑图. HotSpot虚拟机对象 ...

  3. [db2]数据备份与还原

    前言 备份还原db2数据库一般有两种方式,一种是使用db2 backup + db2 restore,另一种是db2move + db2look.前者备份的数据库文件不能使用后者的方式进行还原. 实例 ...

  4. centos7升级内核到最新稳定版

    前言 centos7默认的内核版本才3.10,诸如VXLAN.eBPF等特性无法体验,因此需要升级.目前(2022.02)Linux的内核版本已更新到5.16. 步骤 更新仓库 yum update ...

  5. SpringBoot 启动流程追踪(第二篇)

    上一篇文章分析了除 refresh 方法外的流程,并着重分析了 load 方法,这篇文章就主要分析 refresh 方法,可以说 refresh 方法是 springboot 启动流程最重要的一环,没 ...

  6. 使用.NET Jieba.NET 的 PosSegmenter 实现中文分词匹配

    ​ 目录 引言 1. 什么是中文分词 2. Jieba.NET简介 3. PosSegmenter介绍 4. 实现中文分词匹配 4.1 安装Jieba.NET库 4.2 创建PosSegmenter实 ...

  7. Go 并发编程 - runtime 协程调度(三)

    Go Runtime Go runtime 可以形象的理解为 Go 程序运行时的环境,类似于 JVM.不同于 JVM 的是,Go 的 runtime 与业务程序直接打包在一块,是一个可执行文件,直接运 ...

  8. 交叉编译 Qt5.12 armv8(aarch64) 带 WebEngine - NVIDIA JETSON TX2

    编译平台 Windows10 WSL2 Debian,目标平台 NVIDIA JETSON TX2 (注:Ubuntu <= 16.04 会出现 libclang < 3.8 的问题) 下 ...

  9. Wood,微型 Java ORM 框架(首次发版)

    Wood,微型 Java ORM 框架(支持:java sql,xml sql,annotation sql:事务:缓存:监控:等...),零依赖! 特点和理念: 跨平台:可以嵌入到JVM脚本引擎(j ...

  10. Note -「SOS DP」高维前缀和

    本文差不多算是翻译了一遍 CF blog?id=45223 就是抄了一遍,看不懂可以去原文. 当然我的翻译并不是完全遵从原文的. Part. 1 Introduction 平时我们怎么求高维前缀和?容 ...