Rust切片、结构体、枚举

news2025/7/20 9:58:17

文章目录

    • 切片类型
      • 字符串切片
      • 其他结构的切片
    • 结构体
      • 结构体实例
      • 元组结构体
      • 结构体所有权
      • 输出结构体
      • 结构体的方法
      • 结构体关联函数
      • 单元结构体
    • 枚举
      • match语法
      • Option枚举类
      • if let 语句

切片类型

切片(Slice)是对数据值的部分“引用”

我们可以从一个数据集合中取一部分来使用

字符串切片

例如

fn main() {
    let s = String::from("broadcast");

    let part1 = &s[0..5];
    let part2 = &s[5..9];

    println!("{}={}+{}", s, part1, part2);
}

这里的0..5是前闭后开区间实际上内存上是这样的

image.png

有一些简便的写法,可以这样写

..y 等价于 0..y
x.. 等价于位置 x 到数据结束
.. 等价于位置 0 到结束

被切片引用的字符串是不允许被修改的,除此之外,我们需要区分strString这两个字符串类型

前者指的是堆内存中的字符串,我们可以理解为常量字符串,用的时候是作为&str引用使用的

String实际上是一种数据类型,类似于C++中的string类,有追加,清空等一系列操作

这两者都支持切片,切片的结果必须是引用类型

let slice = &s[0..3];

其他结构的切片

fn main() {
    let arr = [1, 3, 5, 7, 9];
    let part = &arr[0..3];
    for i in part.iter() {
        println!("{}", i);
    }
}

原理都是类似的

结构体

结构体和元组是类似的,可以将不同类型的数据作为一个整体,但是结构体内部每个成员是有名字的

例如

struct Site {
    domain: String,
    name: String,
    nation: String,
    found: u32
}

这里的结构体和C++中的不太一样,这里的结构体只能用来定义类型,不能实例化对象,不需要;,成员用,分割

结构体实例

结构体实例化是使用key: value的形式进行赋值的,例如

let baidu = Site {
    domain: String::from("www.baidu.com"),
    name: String::from("baidu"),
    nation: String::from("China"),
    found: 2013
};

如果当前作用域有和成员变量名称相同的,可以直接写

let domain = String::from("www.baidu.com");
let name = String::from("baidu");
let baidu = Site {
    domain,  // 等同于 domain : domain,
    name,    // 等同于 name : name,
    nation: String::from("China"),
    traffic: 2013
};

如果用一个结构体实例的一部分去构建另一个结构体,可以这样写

let site = Site {
    domain: String::from("www.baidu.com"),
    name: String::from("b"),
    ..baidu
};

但是不允许全部用旧结构体的

元组结构体

元组结构体的定义和使用更为简单,实际上是一种元组形式的结构体,区别就是有名字和固定的类型格式,主要是为了处理定义经常使用的简单类型用的

struct Color(u8, u8, u8);
struct Point(f64, f64);

let black = Color(0, 0, 0);
let origin = Point(0.0, 0.0);

使用方法就和普通的元组使用是一样的了

结构体所有权

结构体实例会掌握所有成员的所有权,因为当结构体生命周期结束的时候,会释放所有字段

输出结构体

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

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

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

第一行是调用调试库,然后用:?做占位符就可以输出整个结构体的内容了,使用:#?就可以自动格式化

结构体的方法

结构体的方法主要是用于操作结构体实例本身的

Rust语言其实不是面向对象的,但是也可以实现面向对象的思想

结构体方法的第一个参数必须是&self,不需要声明类型

例如计算一个矩形的面积

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

fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };
    println!("rect1's area is {}", rect1.area());
}

调用结构体方法的时候就可以不用写self了

结构体关联函数

如果做impl中,但是没有&self参数,而是属于结构体全体的,不属于某个具体的实例

类似于C++中的静态成员函数

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

impl Rectangle {
    fn create(width: u32, height: u32) -> Rectangle {
        Rectangle { width, height }
    }
}

fn main() {
    let rect = Rectangle::create(30, 50);
    println!("{:?}", rect);
}

单元结构体

结构体也可以不需要任何成员

struct UnitStruct;

枚举

Rust的枚举和C++的枚举还是不太一样的,但是使用是比较简单的,例如

#[derive(Debug)]

enum Book {
    Papery, Electronic
}

fn main() {
    let book = Book::Papery;
    println!("{:?}", book);
}

我们可以给枚举添加元组属性描述,或者使用结构体的语法都是可以的

enum Book {
    Papery(u32),
    Electronic(String),
}

let book = Book::Papery(1001);
let ebook = Book::Electronic(String::from("url://..."));


enum Book {
    Papery { index: u32 },
    Electronic { url: String },
}
let book = Book::Papery{index: 1001};

但是我们无法访问具体枚举对应的值是什么,访问的方法在下面介绍

match语法

match很类似switch,但是rust并不支持switch

例如

fn main() {
    enum Book {
        Papery {index: u32},
        Electronic {url: String},
    }
    
    let book = Book::Papery{index: 1001};
    let ebook = Book::Electronic{url: String::from("url...")};
    
    match book {
        Book::Papery { index } => {
            println!("Papery book {}", index);
        },
        Book::Electronic { url } => {
            println!("E-book {}", url);
        }
    }
}

基本格式是这样的

match 枚举类实例 {
    分类1 => 返回值表达式,
    分类2 => 返回值表达式,
    ...
}

但是所有返回值表达式的类型必须是一样的

match除了可以处理枚举,也可以处理整数、浮点数、字符、字符串切片引用的,但是不推荐使用浮点数,有可能有精度问题

默认情况用_表示,例如

fn main() {
    let t = "abc";
    match t {
        "abc" => println!("Yes"),
        _ => {},
    }
}

Option枚举类

Option时Rust标准库自带的枚举类,这主要是为了解决Rust没有空引用的问题

Option具体是这样的

enum Option<T> {
    Some(T),
    None,
}

我们如果要对这个类型的数据做操作的时候,就必须先判断是否时None

fn main() {
    let opt = Option::Some("Hello");
    match opt {
        Option::Some(something) => {
            println!("{}", something);
        },
        Option::None => {
            println!("opt is nothing");
        }
    }
}

如果我们想要声明某个变量是空值时,就必须先声明明确的类型

fn main() {
    let opt: Option<&str> = Option::None;
    match opt {
        Option::Some(something) => {
            println!("{}", something);
        },
        Option::None => {
            println!("opt is nothing");
        }
    }
}

Option是默认引入的,所以可以直接写Some()或者None

if let 语句

这是一种match语句的语法糖,可以用来简化匹配match枚举类型的yufa

如果直接使用if else

let maybe_name = Some("Alice");

if maybe_name {
    println!("Name is: {}", maybe_name); // ❌ 编译错误:不能直接判断 Option
}

正确的方式是使用if let ,当然这个后面可以加上else

let maybe_name = Some("Alice");

if let Some(name) = maybe_name {
    println!("Name is: {}", name); // ✅ 解构出 name
}

对应的match写法是

match maybe_name {
    Some(name) => println!("Name is: {}", name),
    _ => (), // 其它情况忽略
}

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

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

相关文章

【学习笔记】深度学习环境部署相关

文章目录 [AI硬件科普] 内存/显存带宽&#xff0c;从 NVIDIA 到苹果 M4[工具使用] tmux 会话管理及会话持久性[A100 02] GPU 服务器压力测试&#xff0c;gpu burn&#xff0c;cpu burn&#xff0c;cuda samples[A100 01] A100 服务器开箱&#xff0c;超微平台&#xff0c;gpu、…

股票日数据使用_未复权日数据生成前复权日周月季年数据

目录 前置&#xff1a; 准备 代码&#xff1a;数据库交互部分 代码&#xff1a;生成前复权 日、周、月、季、年数据 前置&#xff1a; 1 未复权日数据获取&#xff0c;请查看 https://blog.csdn.net/m0_37967652/article/details/146435589 数据库使用PostgreSQL。更新日…

【LeetCode Solutions】LeetCode 146 ~ 150 题解

CONTENTS LeetCode 146. LRU 缓存&#xff08;中等&#xff09;LeetCode 147. 对链表进行插入排序&#xff08;中等&#xff09;LeetCode 148. 排序链表&#xff08;中等&#xff09;LeetCode 149. 直线上最多的点数&#xff08;困难&#xff09;LeetCode 150. 逆波兰表达式求值…

《 如何更高效地学习》

&#x1f680;个人主页&#xff1a;BabyZZの秘密日记 &#x1f4d6;收入专栏&#xff1a;个人谈心 &#x1f30d;文章目入 一、明确学习目标二、制定学习计划三、选择合适的学习方法&#xff08;一&#xff09;主动学习&#xff08;二&#xff09;分散学习&#xff08;三&#…

分布式数据一致性场景与方案处理分析|得物技术

一、引言 在经典的CAP理论中一致性是指分布式或多副本系统中数据在任一时刻均保持逻辑与物理状态的统一&#xff0c;这是确保业务逻辑正确性和系统可靠性的核心要素。在单体应用单一数据库中可以直接通过本地事务(ACID)保证数据的强一致性。 然而随着微服务架构的普及和业务场…

JAVA:使用 Curator 进行 ZooKeeper 操作的技术指南

1、简述 Apache Curator 是一个基于 ZooKeeper 的 Java 客户端库&#xff0c;它极大地简化了使用 ZooKeeper 的开发工作。Curator 提供了高层次的 API&#xff0c;封装了很多复杂的 ZooKeeper 操作&#xff0c;例如连接管理、分布式锁、Leader 选举等。 在分布式系统中&#…

Linux中的调试器gdb与冯·诺伊曼体系

一、Linux中的调试器&#xff1a;gdb 1.1安装与版本查看 可以使用yum进行安装&#xff1a; yum install -y gdb 版本查看&#xff1a;使用指令 gdb --version 1.2调试的先决条件&#xff1a;release版本与debug版本的切换 debug版本&#xff1a;含有调试信息 release版本…

STM32 + keil5 跑马灯

硬件清单 1. STM32F407VET6 2. STLINK V2下载器(带线) 环境配置 1. 安装ST-LINK 2. 安装并配置 keil5 https://blog.csdn.net/qq_36535414/article/details/108947292 https://blog.csdn.net/weixin_43732386/article/details/117375266 3. 接线并下载 点击"LOAD“&a…

盲盒小程序开发平台搭建:打造个性化、高互动性的娱乐消费新体验

在数字化浪潮席卷消费市场的今天&#xff0c;盲盒小程序以其独特的趣味性和互动性&#xff0c;迅速成为了年轻人追捧的娱乐消费新宠。盲盒小程序不仅为用户带来了拆盒的惊喜和刺激&#xff0c;更为商家提供了创新的营销手段。为了满足市场对盲盒小程序日益增长的需求&#xff0…

DuckDB系列教程:如何分析Parquet文件

Parquet 是一种强大的、基于列的存储格式&#xff0c;适用于实现更快捷和更高效的数据分析。您可以使用 DuckDB 这种内存型分析数据库来处理 Parquet 文件并运行查询以对其进行分析。 在这篇文章中&#xff0c;我们将逐步介绍如何使用 DuckDB 对存储在 Parquet 文件中的餐厅订单…

GRE,MGRE

GRE&#xff1a;静态过程&#xff0c;有局限性 R1 &#xff1a; [r1]interface Tunnel 0/0/0 --- 创建一个虚拟的隧道接口 [r1-Tunnel0/0/0]ip address 192.168.3.1 24 --- 给隧道接口分配一个 IP 地址 [r1-Tunnel0/0/0]tunnel-protocol gre --- 定义接口的封装方式 [r1-Tun…

【linux学习】linux系统调用编程

目录 一、任务、进程和线程 1.1任务 1.2进程 1.3线程 1.4线程和进程的关系 1.5 在linux系统下进程操作 二、Linux虚拟内存管理与stm32的真实物理内存区别 2.1 Linux虚拟内存管理 2.2 STM32的真实物理内存映射 2.3区别 三、 Linux系统调用函数 fork()、wait()、exec(…

Azure Speech 赋能,为智能硬件注入 AI 语音 “新灵魂”

在人工智能技术飞速发展的今天&#xff0c;智能硬件正逐步渗透到人们生活的方方面面。AI玩具、AI眼镜、AI鼠标等创新产品不仅提升了用户体验&#xff0c;更带来了前所未有的交互方式。领驭科技凭借微软Azure Speech的强大技术能力&#xff0c;为硬件厂商提供一站式AI语音解决方…

SignalR给特定User发送消息

1、背景 官网上SignalR的demo很详细&#xff0c;但是有个特别的问题&#xff0c;就是没有详细阐述如何给指定的用户发送消息。 2、解决思路 网上整体解决思路有三个&#xff1a; 1、最简单的方案&#xff0c;客户端连接SignalR的Hub时&#xff0c;只是简单的连接&#xff0c…

React: hook相当于函数吗?

一、Hook 是一个函数&#xff0c;但不仅仅是函数 函数的本质 Hook 确实是一个 JavaScript 函数&#xff0c;例如 useState、useEffect 或自定义 Hook 都是函数。它们可以接受参数&#xff08;如初始状态值或依赖项数组&#xff09;&#xff0c;并返回结果&#xff08;如状态值和…

【数据分享】2002-2023中国湖泊水位变化数据集(免费获取)

湖泊水位变化是研究水资源动态、生态系统演变和气候变化影响的重要指标。湖泊水位的升降不仅反映了降水、蒸发和入流水量的变化&#xff0c;还与人类活动、气候波动及地质过程密切相关。因此&#xff0c;高精度、长时间序列的湖泊水位数据对于水资源管理、洪水预测以及生态环境…

免费送源码:Java+SSM+Android Studio 基于Android Studio游戏搜索app的设计与实现 计算机毕业设计原创定制

摘要 本文旨在探讨基于SSM框架和Android Studio的游戏搜索App的设计与实现。首先&#xff0c;我们详细介绍了SSM框架&#xff0c;这是一种经典的Java Web开发框架&#xff0c;由Spring、SpringMVC和MyBatis三个开源项目整合而成&#xff0c;为开发企业级应用提供了高效、灵活、…

STM32单片机入门学习——第14节: [6-2] 定时器定时中断定时器外部时钟

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.04 STM32开发板学习——第14节: [6-2] 定时器定时中断&定时器外部时钟 前言开发…

2025-04-03 Latex学习1——本地配置Latex + VScode环境

文章目录 1 安装 Latex2 安装 VScode3 配置环境3.1 汉化 VScode3.2 安装 latex 插件3.3 配置解释 4 编译示例5 加快你的编译5.1 取消压缩5.2 使用 PDF 代替图片 6 参考文章 1 安装 Latex 本文配置环境&#xff1a; Windows11 打开清华大学开源软件镜像站&#xff1a;https://mi…

【CF】Day24——Codeforces Round 994 (Div. 2) D

D. Shift Esc 题目&#xff1a; 思路&#xff1a; 典DP的变种 如果这一题没有这个变换操作&#xff0c;那么是一个很典型的二维dp&#xff0c;每一个格子我们都选择上面和左边中的最小值即可 而这题由于可以变换&#xff0c;那我们就要考虑变换操作&#xff0c;首先一个显然…