当前位置: 首页 > article >正文

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>

Example:

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

    // 切片引用就是不可变引用,不可变引用和可变引用是互斥的
    let word = first_word(&s);

    s.clear();

    println!("The first word is: {}", word);
}

fn first_word(s: &str) -> &str {
    let all_bytes = s.as_bytes();

    for (i, &byte) in all_bytes.iter().enumerate() {
        if byte == b' ' {
            return &s[0..i];
        }
    }

    &s[..]
}

编译及测试:

 cargo run
   Compiling project v0.1.0 (/home/wangji/installer/rust/project/ch1_variables)
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
 --> src/main.rs:6:5
  |
4 |     let word = first_word(&s);
  |                           -- immutable borrow occurs here
5 |
6 |     s.clear();
  |     ^^^^^^^^^ mutable borrow occurs here
7 |
8 |     println!("The first word is: {}", word);
  |                                       ---- immutable borrow later used here

For more information about this error, try `rustc --explain E0502`.
error: could not compile `project` (bin "project") due to 1 previous error

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常用数据结构教程

http://www.kler.cn/a/382459.html

相关文章:

  • vscode php Launch built-in server and debug, PHP内置服务xdebug调试,自定义启动参数配置使用示例
  • 制作gif动图并穿插到CSDN文章中
  • 二开CS—上线流量特征shellcode生成修改模板修改反编译打包
  • 拒绝事后背锅:测试项目中的风险管理一定要知道
  • 前端使用Luckysheet把返回的base64或二进制文件流格式,实现xlsx文件预览
  • Angular引用控件类
  • 【K8S系列】Kubernetes 中 Service 更改未生效的故障排查与解决方案【已解决】
  • 智能提醒助理系列-jdk8升级到21,springboot2.3升级到3.3【性能篇】
  • WandB概念、主要功能、详细说明和总结
  • 鸿蒙ArkTS中的布局容器组件(Scroll、List、Tabs)
  • react中得类组件和函数组件有啥区别,怎么理解这两个函数
  • 源文件到可执行文件流程
  • Vue.js组件开发:构建高效、可复用的前端应用
  • 【MATLAB源码-第200期】基于matlab的鸡群优化算法(CSO)机器人栅格路径规划,输出做短路径图和适应度曲线。
  • 蓝桥杯-网络安全比赛题目-遗漏的压缩包
  • 15分钟学 Go 第 30 天:测试基础
  • 11-单字符串多字段查询:Dis Max Query
  • Docker 安装使用操作指南
  • 宠物空气净化器测评!希喂/米家/有哈宠物空气净化器谁性价比高
  • 综合项目--博客
  • 【AIGC】如何充分利用ChatGPT:有效提示框架与基本规则
  • 成绩排序c++
  • D60【python 接口自动化学习】- python基础之数据库
  • 数据结构acwing和洛谷p8085作业
  • 专业 UI 设计公司:为您开启交互设计新征程
  • Linux案例:DNS服务器配置