6.结构体

news2024/11/17 10:22:09

目录

  • 一、普通结构体(struct)
    • 1.1 说明
    • 1.2 举例
      • 1)结构体定义及访问
      • 2)结构体初化的简单写法
      • 3)结构体更新语法
  • 二、元组结构体(tuple struct)
    • 2.1 概念
    • 2.2 示例
  • 三、类单元结构体(unit-like structs)
    • 3.1 概念
    • 3.2 举例
  • 四、类的使用示例
  • 五、为结构体添加实现方法
    • 5.1 概念
    • 5.2 举例
  • 六、关联函数
    • 6.1 概念
    • 6.2 示例

一、普通结构体(struct)

1.1 说明

  • 需要为所有字段定义名称及类型
  • 结构体可以作为函数的返回值
  • 一旦struct的实例是可变的,那么实例中所有字段都是可变的
  • 实例化时,结构体字段的顺序不需要和它们在声明的的顺序一致

1.2 举例

1)结构体定义及访问

//定义结构体
struct User {
    username: String,
    email: String,
    sing_in_count: u64,
    active: bool,
}

//得到一个结构体实例(未按照定义时的顺序)
fn get_new_user() -> User {
    User {
        email: String::from("ch@163.com"),
        sing_in_count: 86,
        username: String::from("ch@163.com"),
        active: false,
    }
}

fn main() {

    //定义一个可变的结构体实例
    let mut user1 = User {
        email: String::from("xxx@163.com"),
        username: String::from("xxx"),
        active: true,
        sing_in_count: 556,
    };

    let user2 = get_new_user();

    println!("user1: email = {}", user1.email); //xxx@163.com

    user1.email = String::from("yyy@189.com");  //修改可变的值
    println!("user1: email  = {}", user1.email);  //yyy@189.com
    println!("user2: email  = {}", user2.email);  //ch@163.com
}

2)结构体初化的简单写法

  • 前面得到实例时都要重复写字段名称和变量,过于繁琐;
  • 当字段名与字段值对应变量名相同时,就可以使用字段初始化简写的方式;
fn get_new_user(email: String, username: String) -> User {
    User {
        email,
        sing_in_count: 86,
        username,
        active: false,
    }
}

3)结构体更新语法

  • 通过改变旧实例中少部分值来创建一个新的结构体实例可以使用结构体更新语法
  • .. 旧实例语法指定了剩余未显式设置值的字段应有与给定实例对应字段相同的值;
    *..旧实例必须放在最后,以指定其余的字段应从旧实例的相应字段中获取其值,但我们可以选择以任何顺序为任意字段指定值,而不用考虑结构体定义中字段的顺序;
  • ..旧实例后不能加逗号;
  • 要注意所有权转移的问题
struct User {
    username: String,
    email: String,
    sing_in_count: u64,
    active: bool,
}

fn get_new_user() -> User {
    let username = String::from("ch@163.com");
    let email = String::from("ch@163.com");
    User {
        username,
        email,
        sing_in_count: 86,
        active: false,
    }
}

fn main() {
    let user1 = get_new_user();

    //未采用更新语法
    let user2 = User{
        username: String::from("user2"),
        email: String::from("user2@163.com"),
        sing_in_count: user1.sing_in_count,
        active: user1.active,
    };

    //采用结构体更新语法
    let user3 = User{
        username: String::from("user3"),
        ..user1  //不能写逗号,其它的用user1的赋值
    };
    
    // println!("user1.username = {}", user1.email); //所有权已经转移到user3,所以这里不能使用

    println!("user2.username = {}, sing_in_count = {}", user2.username, user2.sing_in_count);
    println!("user3.username = {}, sing_in_count = {}", user3.username, user3.sing_in_count);
}

二、元组结构体(tuple struct)

2.1 概念

  • 定义与元组类似的结构体,称为元组结构体
  • 元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型
  • 当想给整个元组取一个名字,并使元组成为与其他元组不同的类型时,可以使用元组结构体;
  • 要定义元组结构体,以 struct 关键字和结构体名开头并后跟元组中的类型;

2.2 示例

fn main() {
    struct Color(i32, i32, i32);
    struct Point(i32, i32, i32);

    let black = Color(3, 4, 5);
    let origin = Point(33, 15, 14);

    println!("{} {} {}", black.0, black.1, black.2);
    println!("{} {} {}", origin.0, origin.1, origin.2);
}

三、类单元结构体(unit-like structs)

3.1 概念

  • 类单元结构体是一个没有任何字段的结构体
  • 类似于 (),即单元类型(只有一个值,被称为单元值);
  • 类单元结构体常常在想要在某个类型上实现 trait 但不需要在类型中存储数据的时候发挥作用;

3.2 举例

struct AlwaysEqual;

fn main() {
    let subject = AlwaysEqual;
}
  • 使用struct关键字定义 AlwaysEqual,以分号结尾;
  • 在main函数中,以代码所示的方法获得 AlwaysEqual 的实例变量 subject;
  • 下一步将实现这个类型的行为,即每个实例始终等于每一个其他类型的实例,也许是为了获得一个已知的结果以便进行测试。现在不需要任何数据来实现这种行为。在以后的文章里将会看到如何定义特性并在任何类型上实现它们,包括类单元结构体。

四、类的使用示例

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

//只传递引用,因此不会获取传入变量的所有权
fn area(rect: &Rectangle) -> u32 {
    rect.width * rect.height
}

fn main() {
    let rc = Rectangle{
        width: 53,
        height: 20,
    };

    println!("area = {}", area(&rc));
    println!("rc = {:#?}", rc)
}
  • 代码计算长方体的面积;
  • area传入的是引用,因此不会获得变量的所有权;
  • #[derive(Debug)]与println的{:#?}配合使用是为了查看实体化后rc的值,如果把前者取消并且使用println!("rc={}",rc)打印结果,会得到如下错误
    在这里插入图片描述
    按照说明修改println!的参数再编译会得到如下错误
    在这里插入图片描述
    因此,根据提示一步步修改就会得到正确的结果

五、为结构体添加实现方法

5.1 概念

  • 使用fn关键字和名称声明,可以拥有参数和返回值;
  • 方法在结构体的上下文中被定义(或者是枚举或 trait 对象的上下文),并且第一个参数总是 self,代表调用该方法的结构体实例;
  • 一般将方法的第一个参数写为&self,只希望能够读取结构体中的数据,而不是写入;
  • 想要在方法中改变调用方法的实例,需要将第一个参数改为&mut self
  • 通过仅仅使用 self 作为第一个参数来使方法获取实例的所有权是很少用的;该功能通常用在当方法将 self 转换成别的实例的时候,想要防止调用者在转换之后使用原始的实例。

5.2 举例

  • area方法实现了面积的计算;
  • can_hold方法计算当前对象是否能够包围住第二个Rectangle对象的实例;
#[derive(Debug)]
struct Rectangle{
    width: u32,
    height: u32,
}

impl Rectangle{
    fn area(&self) -> u32{
        self.width * self.height
    }

    fn can_hold(&self, src: &Rectangle) -> bool{
        self.width >= src.width && self.height >= src.height
    }
}

fn main() {
    let rc = Rectangle{
        width: 53,
        height: 20,
    };

    let rc2 = Rectangle{
        width: 51,
        height: 20,
    };

    println!("{}", rc.can_held(&rc2));
}

六、关联函数

6.1 概念

  • 所有在 impl 块中定义的函数被称为关联函数;
  • 可以定义不以 self为第一参数的关联函数(类似于类的静态函数),String::from就是一个关联函数;

6.2 示例

使用关联函数创建正文形并计算面积。

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

impl Rectangle{
    fn area(&self) -> u32{
        self.width * self.height
    }

    fn square(size: u32) -> Rectangle{
        Rectangle{
            width: size,
            height: size,
        }
    }
}

fn main() {
    let rc = Rectangle::square(3);
    println!("rc.area = {}", rc.area());
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1812245.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

贪 吃 蛇

简介 简易贪吃蛇,使用 javax.swing 组件构建游戏界面,通过监听键盘按键实现游戏操纵。 功能设计 按1 - 开始游戏按2 - 重新开始按3 - 暂停/继续按Esc-退出游戏统计吃到的苹果个数(得分)难度控制,得分超过阈值时难度…

计算机内存分类

1,非易失性存储器。 断电时,存储器的内容不会丢失,并且 加电时再次可用。这对于处理器启动或重启时使用的引导代码是必需的。 o ROM:只读存储器;此存储器的内容在制造过程中定义 设备。一旦发生错误,芯片…

推荐系统学习笔记(五)-----双塔模型

目录 双塔模型 训练 pointwise训练 pairwise训练 listwise训练 双塔模型 矩阵补充模型只用到了用户id和物品id,其余属性没有用上 用户属性也可以这样处理 用户塔和物品塔各输出一个向量,两个向量的余弦相似度作为兴趣的预估值 训练 第一种&#x…

VFP发送邮件有哪些配置要求?如何使用VFP?

VFP发送邮件支持的邮件服务器?邮件发送功能怎么优化? 在如今的互联网时代,应用程序发送邮件功能几乎是不可或缺的,VFP也不例外。然而,要实现VFP发送邮件,需要了解并配置相关的要求和步骤。AokSend将详细介…

如何查看个人大数据信用报告?查询报告哪家好呢?

大数据信用报告是现代社会中非常重要的信用评估工具,对于个人来说也具有非常重要的意义。那么,如何查看个人大数据信用报告?查询报告哪家好呢?本文将为您介绍。 首先,查看个人大数据信用报告需要了解报告的内容和格式 一般来说,…

【Python】Flask问答系统Demo项目

学习视频 我是跟着知了传课学的Flask,起初了解Flask还是GPT告诉我的,现在可以说用Flask做后端是真的方便! https://www.bilibili.com/video/BV17r4y1y7jJ 项目结构与下载 FlaskOA(项目文件夹) │ app.py │ conf…

skywalking9.4 链路追踪

下载,很慢很慢很慢!!!! jdk 使用jdk17 skywalking-apm 9.4 java-agent 9.0 idea 本地开发配置 第1行配置按实际来; 第2行自定义,一般和微服务名称相同; 第3行ip写安装的机器ip,端…

同余式,乘法逆元,费马小定理

同余式 同余式是 数论 的基本概念之一,设m是给定的一个正整数,a、b是整数,若满足m| (a-b),则称a与b对模m 同余 ,记为a≡b (mod m),或记为a≡b (m)。 这个式子称为模m的同余式,若m∤ (a-b)&…

机器学习-支持向量机

目录 一支持向量机 1.支持向量机SVM 2构建svm目标函数 3.拉格朗日乘法,kkt条件 拉格朗日乘法: kkt条件 对偶问题 4.最小化SVM目标函数 kkt条件: 对偶转换: 5软间隔及优化 优化svm目标函数 构造拉格朗日函数 对偶转换关系…

orbslam2代码解读(4):loopclosing回环检测线程

书接上回,介绍完了局部建图线程,局部建图线程在进行局部BA之后,也会将新的关键帧mpLoopCloser放进回环线程的mlpLoopKeyFrameQueue容器中。所以这时候回环检测线程就根据这个新的关键帧来进行回环检测的操作。 回环检测的主要程序 // 线程主…

177.二叉树:从前序与中序遍历序列构造二叉树(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

176.二叉树:从中序与后序遍历序列构造二叉树(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

OpenGauss常操作

OpenGauss官网已经有很详细的说明了,但是对于新手而言还有一些需要注意的地方; 安装 yum一键安装; yum -y install libaio-devel yum -y install readline-devel yum -y install libnsl 单独创建用户和组; groupadd dbgroup useradd -g dbgroup omm passwd omm 取消打开文…

DriveWorld:一个预训练模型大幅提升检测+地图+跟踪+运动预测+Occ多个任务性能

1. 写在前面 以视觉为中心的自动驾驶技术近期因其较低的成本而引起了广泛关注,而预训练对于提取通用表示至关重要。然而,当前的以视觉为中心的预训练通常依赖于2D或3D预训练任务,忽视了自动驾驶作为4D场景理解任务的时序特征。这里通过引入一…

中国最受欢迎起名大师,国内顶级的姓名学大师是谁

唐王古镇龙泉边, 端午邀约凤凰山, 举国共享康宁日, 泉星福瑞天下安… 颜廷利敬献---福祐安康 中国最受欢迎起名大师,国内顶级的姓名学大师是谁?在齐鲁的心脏,济南的历史悠长的唐王古镇边,龙泉大…

香港优才是不是智商税?搞懂香港身份不后悔

很多中产家庭和明星通过不同方式获得香港身份,以享受其诸多优势,如子女教育和事业发展。明星如孙俪/邓超夫妇、汤唯、朗朗、章子怡和黄晓明等都获得了香港身份。 一、香港身份「优才计划」是什么?是否值得追求? 香港身份&#xf…

知识管理与集体创新——从企业到新型研发机构的实践与思考︱PMO大会

全国PMO专业人士年度盛会 鹏城实验室人力资源处人才发展主管,原华为供应链管理部知识管理负责人王万翎女士受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾,演讲议题为“知识管理与集体创新——从企业到新型研发机构的实践与思考”。大会将于6月29-…

springboot在线雅思学习平台 -计算机毕业设计源码44566

目 录 摘要 1 绪论 1.1系统背景 1.2课题背景及目的 2 1.3系统开发技术的特色 3 1.4 springboot框架介绍 3 1.5论文结构与章节安排 4 2 在线雅思学习平台系统分析 5 2.1 可行性分析 5 2.2 系统流程分析 5 2.2.1数据增加流程 5 2.2.2数据修改流程 6 2.2.3数据删除流程 6 2.3 …

Autoware 定位之EKF 滤波定位(四)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务,并且需要GPU资源,可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU,按时收费每卡2.6元,月卡只需要1.7元每小时&…

网络抓取的最佳用户代理 2024 | 避免在抓取时被禁止使用 UA

你是经常进行网页抓取的人吗?你对你的隐私非常小心吗?那么你一定多次听说过“用户代理”。你知道什么是用户代理吗?它如何影响我们的在线生活呢? 请开始阅读,你会对这篇博客中的一切感兴趣! 什么是用户代…