Rust常用数据结构教程 String与str,元组和数组

文章目录

  • 一、String与&str
    • 1.Rust中的字符串
    • 2.String与&str的区别
    • 3.Vec源码
    • 4. str与&str
    • 5.&str与String的区别总结
    • 6.什么时候用String、什么时候用&str
    • 7.Example
  • 二、元组与数组
  • 参考

一、String与&str

Rust中String的源码

#[derive(PartialEq, PartialOrd, Eq, Ord)]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), lang = "String")]
pub struct String {
vec: Vec<u8>,
}

我们可以看到String是一个结构体
· Vec<u8>
·Vec可变数组,具体内容会在第三章
·u8是无符号整数类型,可以表示0-255之间的数

如何从01到字符串
·0101100110011010 10101001 10101011 10110110=>“原子之音"
需要解决两个问题
·需要知道何时结束

  • 一种是存储结束符
  • 一种是在开始存储len

如何编码,最常用的编码方式

  • ASCII一个字节对应一个字符(可以表示0-255个字符)
  • UTF-8一个到四个字节对应(可以辨识所有语言的字符,除了私人语言,而且可以兼容ASCII

注:一个字节8位,大家知道为啥String内置u8的可变数组(Vec)

1.Rust中的字符串

·选择在开始长度存储
·所有的string都是utf-8
·字符串默认不可变

2.String与&str的区别

·String是结构体而&str是切片的引用
·从实体上讲String类型与str类型,因为&str没有所有权

String

  • string_item
  • pointer:0x213342312c011 —>指向heap中的头一个字符的地址,如"hello""h’,‘e’, “I’… 中的h
  • length:3 具体个数
  • Capacity:10 扩容一般翻倍

3.Vec源码

pub struct Vec<T, #[unstable(feature = "allocator_api'", issue = "32838")] A:Alocator=Global>
{
buf: RawVec<T, A>,
len: usize, //长度
}


pub(crate) struct RawVec<T, A: Allocator = Global> {
ptr: Unique<T>, // 指向
cap: usize, // capacity
alloc: A,
}

4. str与&str

·一个不应存在的数据类型:切片(Rust看来)
·str就是字符串切片,就是数组切片[u8],就是动态大小的utf8字节
·str在Rust是无法直接使用的,我们经常使用&str

  • Box<str>
  • Rc<str>
  • Arc<str>

5.&str与String的区别总结

·String具有所有权,而&str只是切片引用
·String的数据必须存储在heap上,而&str要看引用所代指可以在stack和data section上,也可以在heap上

6.什么时候用String、什么时候用&str

. String

  • 创建需要所有权的字符,有修改需求的

&str

  • 查找,只读

7.Example

String与&str的区别,与相互转换
如何通过&[u8]转换为String
&str与生命周期

fn rust_say() -> &'static str {
    r#"Rust said "str" is danger"#
}

// &[u8] u8数组的切片引用
// 调用第三库 &[u8] -> String
fn u8_to_string(string_data: &[u8]) -> String {
    // String::from_utf8_lossy(string_data).to_string()
    // 在迭代器中使用 &s,意味着对 &u8 引用进行解引用,获取 u8 的值,
    // string_data.iter().map(|&s| s as char).collect()
    string_data.iter().map(|&s| s as char).collect()
}

fn main() {
    // string &str
    // 创建容量为0的空字符串
    let mut item = String::new();
    println!("String {}: cap {}", item, item.capacity());
    item.push('c');
    println!("String {}: cap {}", item, item.capacity());

    // 创建容量为10的空字符串
    let item = String::with_capacity(10);
    println!("String {}: cap {}", item, item.capacity());

    // &str-> String
    let item = String::from("hello world");
    println!("String {}: cap {}", item, item.capacity());
    let item = "hello world".to_string();
    println!("String {}: cap {}", item, item.capacity());

    // Sting->&str
    let i = &item; //&item的类型就是 &str

    // static'str
    println!("{}", rust_say());
    // 创建&str的两种方法:
    const C_S: &str = "";
    let yzzy = "yzzy";

    // &str => &u8
    println!("u8 to String: {}", u8_to_string(yzzy.as_bytes()));

    // &u8的打印
    for item in yzzy.as_bytes() {
        println!("item {}", item);
    }
}

编译及运行

 cargo run 
warning: unused variable: `i`
  --> src/main.rs:31:9
   |
31 |     let i = &item; //&item的类型就是 &str
   |         ^ help: if this is intentional, prefix it with an underscore: `_i`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: constant `C_S` is never used
  --> src/main.rs:36:11
   |
36 |     const C_S: &str = "";
   |           ^^^
   |
   = note: `#[warn(dead_code)]` on by default

warning: `data_struct` (bin "data_struct") generated 2 warnings
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/data_struct`
String : cap 0
String c: cap 8
String : cap 10
String hello world: cap 11
String hello world: cap 11
Rust said "str" is danger
u8 to String: yzzy
item 121
item 122
item 122
item 121

二、元组与数组

元组与数组都是有所有权的数据类型

元组与数组都属于序列类型的复合结构

·元组

  • 可以包含各种类型值的组合

数组

  • 包含同一类型的数据组合

数组注意和切片的关系

fn u8_to_string(string_data: &[u8]) -> String {
    string_data.iter().map(|&s| s as char).collect()
}

#[derive(Debug)]
struct User {
    name: String,
    age: i32,
}

fn main() {
    // 元组
    let tup = (
        1,
        2,
        "hello",
        User {
            name: "y".to_owned(),
            age: 45,
        },
    );
    println!("tup {} {} {} {:?}", tup.0, tup.1, tup.2, tup.3);
    let (a, b, c, d) = tup;
    println!("a {} b {} c {} d {:#?}", a, b, c, d);

    // 数组
    let my_array = [1, 2, 3, 4];
    // let my_array: [i32;4] = [1,2,3,4];
    // let my_array: [i32;3] = [1, 2, 3];

    // 数组与切片
    let my_slice = &my_array[1..3];
    println!("my_array len {}", my_array.len());
    println!("my_slice len {}", my_slice.len());

    let u8_array = [121u8, 122u8, 122u8, 121u8];
    // &u8
    let u8_slice_ref = &u8_array[0..4]; //&[u8]
                                        // &u8_array u8_slice_ref 和 &u8_array是没有区别的
    println!("{:#?}", u8_to_string(&u8_array));
    println!("{:#?}", u8_to_string(u8_slice_ref));
}

编译及运行

 cargo run 
   Compiling data_struct v0.1.0 (/home/wangji/installer/rust/data_struct/data_struct)
warning: fields `name` and `age` are never read
 --> src/main.rs:7:5
  |
6 | struct User {
  |        ---- fields in this struct
7 |     name: String,
  |     ^^^^
8 |     age: i32,
  |     ^^^
  |
  = note: `User` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
  = note: `#[warn(dead_code)]` on by default

warning: `data_struct` (bin "data_struct") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 16.01s
     Running `target/debug/data_struct`
tup 1 2 hello User { name: "y", age: 45 }
a 1 b 2 c hello d User {
    name: "y",
    age: 45,
}
my_array len 4
my_slice len 2
"yzzy"
"yzzy"

参考

  • Rust常用数据结构教程

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

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

相关文章

【科研绘图】如何使用3DMAX进行科研绘图?

3DMAX&#xff08;通常指3ds Max&#xff09;是一款功能强大的三维建模、动画和渲染软件&#xff0c;广泛应用于科研绘图领域。以下是一些关于使用3DMAX进行科研绘图的基本步骤和技巧&#xff1a; 一、基本步骤 创建基本模型 根据科研需求&#xff0c;使用3DMAX的创建工具&…

使用Python Flask实战构建Web应用

你是否曾想过&#xff0c;使用Python来快速搭建一个Web应用&#xff1f;Flask作为一个轻量级的Web框架&#xff0c;因其简单、灵活且高效&#xff0c;成为了很多开发者首选的工具。今天&#xff0c;就让我们一同走进Flask的世界&#xff0c;探索如何使用它轻松构建一个实战Web应…

CSS画icon图标系列(一)

目录 前言&#xff1a; 一、向右箭头 1.原理&#xff1a; 2.代码实现 3.结果展示&#xff1a; 二、钟表 1.原理&#xff1a; 2.代码展示&#xff1a; 3.最终效果&#xff1a; 三、小手机 1.原理&#xff1a; 2.代码展示&#xff1a; 3.最后效果&#xff1a; 四、结…

分类 classificaton

1&#xff09;什么是分类&#xff1f; 在此之前&#xff0c;我们一直使用的都是回归任务进行学习&#xff1b;这里我们将进一步学习什么是分类&#xff0c;我们先从训练模型的角度来看看二者的区别。 对于回归来说&#xff0c;它所作的是对模型输入相应的特征&#xff0c;然后…

免费且强大的PDF转换工具——PDFgear

前言 PDFgear是一款不可或缺的PDF文件处理工具&#xff0c;凭借其强大的功能和多样的特点&#xff0c;它能帮助用户更快速、高效地编辑和处理PDF文件&#xff0c;显著提升工作效率 通过网盘分享的文件&#xff1a;pdf转换工具 链接: https://pan.baidu.com/s/1ap37H9tP6brqTgf…

sql中判断一个字段是否包含一个数据的方法有哪些?

目录 一、like模糊查询&#xff08;like关键字&#xff09; 二、locate(字符串&#xff0c;字段名) 三、 instr(字段名,字符串) 四、regexp_extract(subject, pattern, index) 以下是几种方法&#xff0c;使用hive来举例演示一下&#xff1a; -- 举例&#xff1a;创建一个…

STM32 + CubeMX + 硬件SPI + W5500 +TcpClient

这篇文章记录一下STM32W5500TCP_Client的调试过程&#xff0c;实现TCP客户端数据的接收与发送。 目录 一、W5500模块介绍二、Stm32CubeMx配置三、Keil代码编写1、添加W5500驱动代码到工程&#xff08;添加方法不赘述&#xff0c;驱动代码可以在官网找&#xff09;2、在工程中增…

C++笔试题之实现一个定时器

一.定时器&#xff08;timer&#xff09;的需求 1.执行定时任务的时&#xff0c;主线程不阻塞&#xff0c;所以timer必须至少持有一个线程用于执行定时任务 2.考虑到timer线程资源的合理利用&#xff0c;一个timer需要能够管理多个定时任务&#xff0c;所以timer要支持增删任务…

Halcon resistor.hedv 使用多个对焦级别提取深度

depth_from_focus * Extract depth using multiple focus levels * 使用多个对焦级别提取深度 Names : [] * 初始化一个空数组&#xff0c;用于存储图像名称 dev_close_window () * 关闭当前打开的图像窗口 for i : 1 to 10 by 1 * 循环开始&#xff0c;从1到10 …

区块链技术与应用-PKU 学习笔记

课程地址 资料&#xff1a; ETH-Security 区块链学习记录_比特币 BTC 密码学原理 比特币&#xff0c;又称加密货币(crypto-currency)&#xff0c;它主要利用了密码学中的哈希函数(cryptographic hash function)的抗碰撞特性(collision resistance)和单向散列特性(hiding) …

Spark 的Standalone集群环境安装与测试

目录 一、Standalone 集群环境安装 &#xff08;一&#xff09;理解 Standalone 集群架构 &#xff08;二&#xff09;Standalone 集群部署 二、打开监控界面 &#xff08;一&#xff09;master监控界面 &#xff08;二&#xff09;日志服务监控界面 三、集群的测试 &a…

VLAN 高级技术 ——QinQ的配置

QinQ的概述&#xff1a; QinQ技术是一种扩展虚拟局域网&#xff08;VLAN&#xff09;数量空间的技术&#xff0c;通过在802.1Q标签报文的基础上再增加一层802.1Q的Tag来实现。以下是对QinQ技术的详细概述&#xff1a; QinQ技术的定义与背景 定义&#xff1a;QinQ&#xff08…

伍光和《自然地理学》电子书(含考研真题、课后习题、章节题库、模拟试题)

《自然地理学》&#xff08;第4版&#xff09;由伍光和、王乃昂、胡双熙、田连恕、张建明合著&#xff0c;于2018年11月出版。作为普通高等教育“十一五”国家级规划教材&#xff0c;本书不仅适用于高校地球科学各专业的基础课程&#xff0c;还可供环境、生态等有关科研、教学人…

迅为RK3588开发板Android多屏显示之多屏同显和多屏异显

迅为RK3588开发板是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像…

登录功能设计(php+mysql)

一 登录功能 1. 创建一个登录页面&#xff08;login.php&#xff09;&#xff0c;包含一个表单&#xff0c;用户输入用户名和密码。 2. 在表单的提交事件中&#xff0c;使用PHP代码处理用户输入的用户名和密码。 3. 首先&#xff0c;连接MySQL数据库。然后&a…

vue--vueCLI

何为CLI ■ CLI是Command-Line Interface,俗称脚手架. ■ 使用Vue.js开发大型应用时&#xff0c;我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情。&#xff08;vue 脚手架的作用&#xff09;&#xff0c; 而通过vue-cli即可&#xff1a;vue-cli 可以…

软件测试工程师面试整理 —— 编程与自动化!

在软件测试领域&#xff0c;编程与自动化是提升测试效率、覆盖率和可靠性的关键因素。掌握编程技术和自动化测试框架&#xff0c;能够帮助测试人员有效地执行大量重复性测试任务&#xff0c;并迅速反馈软件的质量状况。以下是编程与自动化在测试中的主要应用及相关技术介绍&…

宝顶白芽,慢生活的味觉盛宴

在快节奏的生活中&#xff0c;人们愈发向往那种悠然自得、返璞归真的生活方式。白茶&#xff0c;以其独特的韵味和清雅的风格&#xff0c;成为了现代人追求心灵宁静与生活品质的象征。而在众多白茶之中&#xff0c;竹叶青茶业出品的宝顶白芽以其甘甜醇爽的特质&#xff0c;成为…

安卓APP渗透安全测试

1.移动安全测试点分析 1.1主要测试 客户端 数据传输 服务端 l反编译 l二次打包 l组件安全 lWebview漏洞 l数据安全 l界面劫持 l数据备份风险 lDebug调试风险 l安全策略 l数据窃听 l中间人攻击 l信息泄露 l任意修改数据包 lSQL注入 l上传漏洞 l暴力破解 l逻辑漏洞 lXSS…