当前位置:首页 > 科技  > 软件

Rust结构体的定义和实例化

来源: 责编: 时间:2024-01-02 17:28:31 364观看
导读结构体特点Rust的结构体跟元组类型比较类似,它们都包含多个相关的值。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组

结构体特点

Rust的结构体跟元组类型比较类似,它们都包含多个相关的值。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。UrA28资讯网——每日最新资讯28at.com

定义结构体,需要使用 struct 关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,一般称为 字段(field)。UrA28资讯网——每日最新资讯28at.com

UrA28资讯网——每日最新资讯28at.com

结构体定义和实例化

下面是一个结构体定义的示例:UrA28资讯网——每日最新资讯28at.com

struct User {    active: bool,    username: String,    email: String,    sign_in_count: u64,}

一旦定义了结构体后,为了使用它,通过为每个字段指定具体值来创建这个结构体的 实例。创建一个实例需要以结构体的名字开头,接着在大括号中使用 key: value 键 - 值对的形式提供字段,其中 key 是字段的名字,value 是需要存储在字段中的数据值。实例中字段的顺序不需要和它们在结构体中声明的顺序一致。换句话说,结构体的定义就像一个类型的通用模板,而实例则会在这个模板中放入特定数据来创建这个类型的值。UrA28资讯网——每日最新资讯28at.com

下面是一个结构体的应用示例:UrA28资讯网——每日最新资讯28at.com

fn main() {    let mut user1 = User {        active: true,        username: String::from("suntiger"),        email: String::from("suntiger@example.com"),        sign_in_count: 1,    };    user1.email = String::from("anotheremail@example.com");}

整体代码如下:UrA28资讯网——每日最新资讯28at.com

UrA28资讯网——每日最新资讯28at.com

将代码进行编译, 可以发现email的内容被替换了,如图:UrA28资讯网——每日最新资讯28at.com

UrA28资讯网——每日最新资讯28at.com

注意看接收结构体实例的user1变量, 前面有mut关键字, 这样方便我们修改结构体成员, 注意整个结构体实例必须是可变的, Rust不允许只将结构体的某个字段标记为可变。UrA28资讯网——每日最新资讯28at.com

在函数中使用结构体

先来看一段在函数中返回结构体实例的代码:UrA28资讯网——每日最新资讯28at.com

fn build_user(email: String, username: String) -> User {    User {        active: true,        username: username,        email: email,        sign_in_count: 1,    }}

我们定义了一个build_user 函数,它返回一个带有给定的 email 和用户名的 User 结构体实例。active 字段的值为 true,并且 sign_in_count 的值为 1。需要注意同其他任何表达式一样,我们可以在函数体的最后一个表达式中构造一个结构体的新实例,来隐式地返回这个实例。UrA28资讯网——每日最新资讯28at.com

字段初始化简化方式

为函数参数起与结构体字段相同的名字是可以理解的,但是不得不重复 email 和 username 字段名称与变量会让人感到厌烦。如果结构体有更多字段,重复每个名称就更使人抓狂。还好Rust准备了简化的方法。UrA28资讯网——每日最新资讯28at.com

先看下面的代码:UrA28资讯网——每日最新资讯28at.com

fn build_user(email: String, username: String) -> User {    User {        active: true,        username,        email,        sign_in_count: 1,    }}

参数名与字段名都完全相同,我们可以使用 字段初始化简写语法来重写 build_user,这样其行为与之前完全相同,无需在字段后面跟上相同名称的字段内容。UrA28资讯网——每日最新资讯28at.com

结构体更新语法

使用旧实例的大部分值但改变其部分值来创建一个新的结构体实例通常是很有用的。这可以通过结构体更新语法实现。UrA28资讯网——每日最新资讯28at.com

看下面的应用代码:UrA28资讯网——每日最新资讯28at.com

fn main() {    let user2 = User {        active: user1.active,        username: user1.username,        email: String::from("another@example.com"),        sign_in_count: user1.sign_in_count,    };}

使用结构体更新语法,我们可以通过更少的代码来达到相同的效果,看下面的代码:UrA28资讯网——每日最新资讯28at.com

fn main() {    let user2 = User {        email: String::from("another@example.com"),        ..user1    };}

.. 语法指定了剩余未显式设置值的字段应有与给定实例对应字段相同的值。与此同时这段代码也在 user2 中创建了一个新实例,但该实例中 email 字段的值与 user1 不同,而 username、 active 和 sign_in_count 字段的值与 user1 相同。..user1 必须放在最后,以指定其余的字段应从 user1 的相应字段中获取其值,但我们可以选择以任何顺序为任意字段指定值,而不用考虑结构体定义中字段的顺序。UrA28资讯网——每日最新资讯28at.com

元组结构体

也可以定义与元组类似的结构体,称为 元组结构体。元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型。当你想给整个元组取一个名字,并使元组成为与其他元组不同的类型时,元组结构体是很有用的,这时像常规结构体那样为每个字段命名就显得多余和形式化了。UrA28资讯网——每日最新资讯28at.com

要定义元组结构体,以 struct 关键字和结构体名开头并后跟元组中的类型。看下面这段代码:UrA28资讯网——每日最新资讯28at.com

struct Color(i32, i32, i32);struct Point(i32, i32, i32);fn main() {    let black = Color(0, 0, 0);    let origin = Point(0, 0, 0);}

注意 black 和 origin 值的类型不同,因为它们是不同的元组结构体的实例。我们定义的每一个结构体有其自己的类型,即使结构体中的字段可能有着相同的类型。例如,一个获取 Color 类型参数的函数不能接受 Point 作为参数,即便这两个类型都由三个 i32 值组成。在其他方面,元组结构体实例类似于元组,你可以将它们解构为单独的部分,也可以使用 . 后跟索引来访问单独的值,等等。UrA28资讯网——每日最新资讯28at.com

类单元结构体

我们也可以定义一个没有任何字段的结构体!它们被称为 类单元结构体, 因为它们类似于unit 类型。类单元结构体常常在你想要在某个类型上实现 trait 但不需要在类型中存储数据的时候发挥作用。UrA28资讯网——每日最新资讯28at.com

定义代码如下:UrA28资讯网——每日最新资讯28at.com

struct AlwaysEqual;fn main() {    let subject = AlwaysEqual;}

要定义 AlwaysEqual,同样也使用 struct 关键字,然后后面跟想要的名称,然后是一个分号。不需要花括号或圆括号!然后,我们可以以类似的方式在 subject 变量中获得 AlwaysEqual 的实例:使用我们定义的名称,不需要任何花括号或圆括号。想象一下,我们将实现这个类型的行为,即每个实例始终等于每一个其他类型的实例,也许是为了获得一个已知的结果以便进行测试。我们不需要任何数据来实现这种行为。UrA28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-56424-0.htmlRust结构体的定义和实例化

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 多个线程为竞争资源而相互等待,导致程序无法继续执行

下一篇: 在 Go 项目中封装 AES 加解密客户端接口

标签:
  • 热门焦点
  • 6月安卓手机好评榜:魅族20 Pro蝉联冠军

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年6月1日至6月30日,仅限国内市场。第一名:魅族20 Pro好评率:95%5月份的时候魅族20 Pro就是
  • K6:面向开发人员的现代负载测试工具

    K6 是一个开源负载测试工具,可以轻松编写、运行和分析性能测试。它建立在 Go 和 JavaScript 之上,它被设计为功能强大、可扩展且易于使用。k6 可用于测试各种应用程序,包括 Web
  • K8S | Service服务发现

    一、背景在微服务架构中,这里以开发环境「Dev」为基础来描述,在K8S集群中通常会开放:路由网关、注册中心、配置中心等相关服务,可以被集群外部访问;图片对于测试「Tes」环境或者
  • SpringBoot中使用Cache提升接口性能详解

    环境:springboot2.3.12.RELEASE + JSR107 + Ehcache + JPASpring 框架从 3.1 开始,对 Spring 应用程序提供了透明式添加缓存的支持。和事务支持一样,抽象缓存允许一致地使用各
  • 量化指标是与非:挽救被量化指标扼杀的技术团队

    作者 | 刘新翠整理 | 徐杰承本文整理自快狗打车技术总监刘新翠在WOT2023大会上的主题分享,更多精彩内容及现场PPT,请关注51CTO技术栈公众号,发消息【WOT2023PPT】即可直接领取
  • 如何通过Python线程池实现异步编程?

    线程池的概念和基本原理线程池是一种并发处理机制,它可以在程序启动时创建一组线程,并将它们置于等待任务的状态。当任务到达时,线程池中的某个线程会被唤醒并执行任务,执行完任
  • 一文搞定Java NIO,以及各种奇葩流

    大家好,我是哪吒。很多朋友问我,如何才能学好IO流,对各种流的概念,云里雾里的,不求甚解。用到的时候,现百度,功能虽然实现了,但是为什么用这个?不知道。更别说效率问题了~下次再遇到,
  • 最“俊美”淘宝卖家,靠直播和短视频圈粉,上架秒光,年销3000万

    来源 | 电商在线文|易琬玉编辑|斯问受访店铺:Ringdoll戒之人形图源:微博@御座的黄山、“Ringdoll戒之人形”淘宝店铺有关外貌的评价,黄山已经听累了。生于1985年的他,哪
  • 签约井川里予、何丹彤,单视频点赞近千万,MCN黑马永恒文希快速崛起!

    来源:视听观察永恒文希传媒作为一家MCN公司,说起它的名字来,可能大家会觉得有点儿陌生,但是说出来下面一串的名字之后,或许大家就会感到震惊,原来这么多网红,都签约这家公司了。根
Top