复合 类型

字符串和切片

切片

切片的作用是允许你引用集合中部分连续的元素序列,而不是引用整个集合。

例如:

let s = String::from("hello world");

let hello = &s[0..5];  // 切片 [0,5)  等效于&s[..5]
let world = &s[6..11];  // 切片 [6,11) 等效于&s[6..]
// 完整的s,&s[..]

注意,方括号中的数字是字节,如果字符是多字节的(如汉字),这时如果切片没有落在两个字符之间,程序就会崩溃(汉字是三个字节,切片0-2就会崩溃)

字符串的切片类型是 &str,i32数组的切片类型是 &[i32]

这样一段代码:let s = "Hello world!";, s 是个切片类型,实际上代码为:let s: &str = "Hello world!"

字符串

Rust中字符是 Unicode 类型。内存占用 从1 - 4 个字节空间。

Rust中常用的字符串类型有 str / String,str硬编码不可变,String可变。

// &str --> String
String::from("Hello world");
"hello world".to_string();

// String --> &str
&s;

操作字符串

let mut s = String::from("Hello ");
// 追加字符串
s.push_str("rust");
// 追加字符
s.push('!');
// 插入字符
s.insert(5, ',');
// 插入字符串
s.insert_str(6, " I like");

// 替换
// replace 适用于 String 和 &str,替换所有,返回一个新字符串,而不是操作原来的字符串
let new_string_replace = string_replace.replace("rust", "RUST");
// replacen 适用于 String 和 &str, 替换指定个数,返回一个新字符串,而不是操作原来的字符串
let new_string_replacen = string_replace.replacen("rust", "RUST", 1);
// replace_range 适用于 String,替换指定范围字符串,操作原来的字符串
string_replace_range.replace_range(7..8, "R");

// 删除
// 均是操作原来的字符串
// pop 删除并返回最后一个字符
let p1 = string_pop.pop();
// remove 删除并返回指定位置字符
string_remove.remove(0);
// truncate 删除指定位置到结尾
string_truncate.truncate(3);
// clear 清空字符串
string_clear.clear();

// 连接
// + += ,右面必须是字符串的切片引用类型,相当于调用std::string add(),返回一个新字符串
let result = string_append + &string_rust;
// format! 
let s = format!("{} {}!", s1, s2);

遍历字符串

// 以 unicode 字符方式遍历字符串
for c in "中国人".chars() {
    println!("{}", c);
}

元组

元组是由多种类型组合到一起形成的,因此它是复合类型,元组的长度是固定的,元组中元素的顺序也是固定的。

fn main() {
    let tup: (i32, f64, u8) = (500, 6.4, 1);
}

使用元组:

fn main() {
    let tup = (500, 6.4, 1);
    
	// 模式匹配
    let (x, y, z) = tup;
    println!("The value of y is: {}", y);
    
    // .
    let five_hundred = x.0;
    let six_point_four = x.1;
    
    // 函数
    let s1 = String::from("hello");
    let (s2, len) = calculate_length(s1);
}

fn calculate_length(s: String) -> (String, usize) {
    let length = s.len(); // len() 返回字符串的长度
    (s, length)
}

结构体

使用

结构体的定义:

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

结构体的创建和使用:

// 每个都需要初始化,顺序可以打乱
let mut user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

// 访问字段,
// **必须要将结构体实例声明为可变的,才能修改其中的字段,Rust 不支持将某个结构体某个字段标记为可变。**
user1.email = String::from("anotheremail@example.com");

// 简化创建
fn build_user(email: String, username: String) -> User {
    User {
        email,
        username,
        active: true,
        sign_in_count: 1,
    }
}

// 更新
let user2 = User {
    email: String::from("another@example.com"),
    ..user1  // 注意 username 发生了所有权转移,不能再被user1使用
};

内存排列

struct File {
    name: String,
    data: Vec<u8>,
}

内存结构:

元组结构体

元组结构体的字段没有名称:

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

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

使用的使用可以直接用 x,y,z / r,g,b

单元结构体

单元结构体没有任何字段和属性

struct AlwaysEqual;

let subject = AlwaysEqual;

// 我们不关心 AlwaysEqual 的字段数据,只关心它的行为,因此将它声明为单元结构体,然后再为它实现某个特征
impl SomeTrait for AlwaysEqual {

}

结构体的所有权

如果你想在结构体中使用一个引用,就必须加上生命周期,否则就会报错!

生命周期篇再写。

打印

  • 使用 #[derive(Debug)] 来打印结构体信息。

    println!("{:?}",struct);

    dbg!(&struct);

  • 也可以实现 Display 特征打印信息(类似 toString() 方法)

    println!("{}",struct);

枚举

使用:

可以向其他语言一样直接使用,也可以为其关联数据信息

// enum PokerSuit {
//   Clubs,
//   Spades,
//   Diamonds,
//   Hearts,
// }

enum PokerCard {
    Clubs(u8),
    Spades(u8),
    Diamonds(u8),
    Hearts(u8),
}

fn main() {
   let c1 = PokerCard::Spades(5);
   let c2 = PokerCard::Diamonds(13);
}

更为复杂的:

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let m1 = Message::Quit;
    let m2 = Message::Move{x:1,y:1};
    let m3 = Message::ChangeColor(255,255,0);
}

使用Option枚举处理空值

在rust中使用Option枚举来处理对象为空的情况(null):

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

使用的使用将值存入 Some<T> 中,这样在使用变量的时候因为不能直接使用 Option,所以需要将值取出来再用。而取出来的时候需要判断值不是Option::None才能用,相当于变相强制进行了判空操作,放置了空指针异常。

数组

在Rust中有两种数组,一种是长度固定吗,速度快的 array,一种是长度动态,性能较低的 vector。

array存储在栈上,vector存储在堆上。

array

使用:

fn main() {
    // 1.定义
    // let a: [i32; 5] = [1, 2, 3, 4, 5];  声明类型
    let a = [1, 2, 3, 4, 5];
    // 重复:5个3
    let a = [3; 5]; 
    // 非基础元素
    // let array = [String::from("rust is good!"); 8];  ×  不能深拷贝
    let array: [String; 8] = std::array::from_fn(|i| String::from("rust is good!"));
    
    // 2.访问
    let first = a[0]; // 获取a数组第一个元素
}

数组切片

  • 创建切片的代价非常小,因为切片只是针对底层数组的一个引用
  • 切片类型[T]拥有不固定的大小,而切片引用类型&[T]则具有固定的大小,因为 Rust 很多时候都需要固定大小数据类型,因此&[T]更有用,&str字符串切片也同理
let a: [i32; 5] = [1, 2, 3, 4, 5];

let slice: &[i32] = &a[1..3];  // 引用

assert_eq!(slice, &[2, 3]);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python学习 -- 类对象从创建到常用函数

在Python编程中&#xff0c;类是一种强大的工具&#xff0c;用于创建具有共同属性和行为的对象。本篇博客将详细介绍Python中类和对象的创建&#xff0c;类的属性和方法&#xff0c;以及一些常用的类函数&#xff0c;通过丰富的代码例子来帮助读者深入理解。 一、类和对象的创…

STM32设置为I2C从机模式(HAL库版本)

STM32设置为I2C从机模式&#xff08;HAL库版本&#xff09; 目录 STM32设置为I2C从机模式&#xff08;HAL库版本&#xff09;前言1 硬件连接2 软件编程2.1 步骤分解2.2 测试用例 3 运行测试3.1 I2C连续写入3.2 I2C连续读取3.3 I2C单次读写测试 4 总结 前言 我之前出过一篇关于…

AI 绘画Stable Diffusion 研究(十)sd图生图功能详解-精美二维码的制作

免责声明: 本案例所用安装包免费提供&#xff0c;无任何盈利目的。 大家好&#xff0c;我是风雨无阻。 为了让大家更直观的了解图生图功能&#xff0c;明白图生图功能到底是干嘛的&#xff0c;能做什么事情&#xff1f;今天我们继续介绍图生图的实用案例-精美二维码的制作。 对…

倒计时动效

1. 效果 2. html <div class"count"><span>3</span><span>2</span><span>1</span> </div>3. css body {width: 100vw;height: 100vh;overflow: hidden;display: flex;justify-content: center;align-items: cente…

【Apollo】阿波罗自动驾驶技术:引领汽车行业革新

前言 Apollo (阿波罗)是一个开放的、完整的、安全的平台&#xff0c;将帮助汽车行业及自动驾驶领域的合作伙伴结合车辆和硬件系统&#xff0c;快速搭建一套属于自己的自动驾驶系统。 开放能力、共享资源、加速创新、持续共赢是 Apollo 开放平台的口号。百度把自己所拥有的强大、…

iTOP-RK3568开发板ubuntu环境下安装Eclipse

eclipse 是使用 Java 语言开发的&#xff0c;一个 Java 应用程序&#xff0c;这意味着 eclipse 只能运行在 Java虚拟机上。倘若没有安装 JDK&#xff08;Java Development Kit&#xff09;&#xff0c;即使在 ubuntu 上安装了 eclipse&#xff0c;也不能运行&#xff0c;所以要…

fastgpt构建镜像

1.把client目录复制到服务器 .next和node_modules文件夹不用上传到服务器 在服务器目录运行 docker build -t fastgpt:1.0.3 . 构建服务 再运行 docker ps 就可以看到容器了

easyexcel合并单元格底色

一、效果图 二、导出接口代码 PostMapping("selectAllMagicExport")public void selectAllMagicExport(HttpServletRequest request, HttpServletResponse response) throws IOException {ServiceResult<SearchResult<TestMetLineFe2o3Export>> result …

Java虚拟机(JVM):垃圾收集算法

目录 一、分代收集理论 二、标记-清除算法 三、标记-复制算法 四、标记-整理算法 一、分代收集理论 分代收集理论建立在两个分代假说之上&#xff1a; 1、弱分代假说&#xff1a;绝大多数对象都是朝生夕灭的。 2、强分代假说&#xff1a;熬过越多次垃圾收集过程的对象就…

mysql 、sql server trigger 触发器

sql server mySQL create trigger 触发器名称 { before | after } [ insert | update | delete ] on 表名 for each row 触发器执行的语句块## 表名&#xff1a; 表示触发器监控的对象 ## before | after : 表示触发的时间&#xff0c;before : 表示在事件之前触发&am…

JVM的元空间了解吗?

笔者近期在面试的时候被问到了这个问题&#xff0c;元空间也是Java8当时的一大重大革新&#xff0c;之前暑期实习求职的时候有专门看过&#xff0c;但是近期秋招的时候JVM相关的内容确实有点生疏了&#xff0c;故在此进行回顾。 结构 首先&#xff0c;我们应了解JVM的堆结构&a…

深入理解python虚拟机:程序执行的载体——栈帧

栈帧&#xff08;Stack Frame&#xff09;是 Python 虚拟机中程序执行的载体之一&#xff0c;也是 Python 中的一种执行上下文。每当 Python 执行一个函数或方法时&#xff0c;都会创建一个栈帧来表示当前的函数调用&#xff0c;并将其压入一个称为调用栈&#xff08;Call Stac…

docker学习(十五)docker安装MongoDB

什么是MongoDB? MongoDB 是一个开源的、面向文档的 NoSQL 数据库管理系统&#xff0c;它以高性能、灵活的数据存储方式而闻名。与传统的关系型数据库不同&#xff0c;MongoDB 采用了一种称为 BSON&#xff08;Binary JSON&#xff09;的二进制 JSON 格式来存储数据。它是一种非…

(详解踩坑)GIT版本回滚git stash、git reset、git reset --hard、git revert

目录 背景 一、&#xff08;git log、git reflog&#xff09;查看git提交日志及命令历史 1.1 git log&#xff08;提交日志&#xff09; 1.2 git reflog&#xff08;命令历史&#xff09; 二、git reset&#xff08;回退到指定的版本&#xff0c;并且保留更改&#xff09; …

IDEA启动报错【java.sql.SQLSyntaxErrorException: ORA-00904: “P“.“PRJ_NO“: 标识符无效】

IDEA报错如下&#xff1a; 2023-08-17 11:26:15.535 ERROR [egrant-biz,b48324d82fe23753,b48324d82fe23753,true] 24108 --- [ XNIO-1 task-1] c.i.c.l.c.RestExceptionController : 服务器异常org.springframework.jdbc.BadSqlGrammarException: ### Error queryin…

leetcode 542. 01 Matrix(01矩阵)

矩阵中只有0&#xff0c;1值&#xff0c;返回每个cell到最近的0的距离。 思路&#xff1a; 0元素到它自己的距离是0&#xff0c; 只需考虑1到最近的0是多少距离。 BFS. 先把元素1处的距离更新为无穷大。 0的位置装入queue。 从每个0出发&#xff0c;走上下左右4个方向&…

axios / fetch 实现 stream 流式请求

axios 是一个支持node端和浏览器端的易用、简洁且高效的http库。本文主要介绍 axios 如何实现 stream 流式请求&#xff0c;注意这里需要区分 node 环境和浏览器环境。 一、node端 代码演示&#xff1a; const axios require(axios);axios({method: get,url: http://tiven.c…

【C# 基础精讲】使用async和await进行异步编程

在C#中&#xff0c;使用async和await关键字进行异步编程是一种强大的工具&#xff0c;可以在不阻塞主线程的情况下执行耗时操作&#xff0c;提高程序的并发性和响应性。本文将深入探讨async和await的基本概念、使用场景、编码规范以及一些示例&#xff0c;以帮助您更好地理解如…

RocketMQ双主双从同步集群部署

&#x1f388; 作者&#xff1a;互联网-小啊宇 &#x1f388; 简介&#xff1a; CSDN 运维领域创作者、阿里云专家博主。目前从事 Kubernetes运维相关工作&#xff0c;擅长Linux系统运维、开源监控软件维护、Kubernetes容器技术、CI/CD持续集成、自动化运维、开源软件部署维护…

定位服务器CPU爆满的具体原因

1、查询CPU消耗的进程 使用top命令查看系统的CPU和内存使用情况 CPU一列是线程占用百分比 2、具体查看某个占分比大的进程 以为PId:7355为例&#xff0c; 执行top -Hp 7355&#xff0c;线程按照CPU使用率排序。 3、将线程PID转化为16进制 执行printf %x 7391&#xff0c;将…