如何理解Rust中的字符串(一)

简介: 如何理解Rust中的字符串(一)
rust中的字符串比较特别,在Rust的核心语言层面,只有一个字符串类型:字符串切片 str(或&str),而String类型是来自于Rust标准库中的类型。

Rust中的字符串是什么?

  • byte的集合
  • 并且它提供了一些方法,这些方法能将byte解析为文本

在Rust的核心语言层面,只有一个字符串类型:字符串切片str(或&str)

字符串切片:对存储在其他地方、utf-8编码的字符串的引用

  • 字符串字面值:存储在二进制文件中,也是字符串切片

切片slice(&str)

Rust还提供了另外一种不持有所有权的类型:切片(slice)

假如我们有这样一个需求,编写一个函数:

  • 它接收字符串作为参数
  • 返回它在这个字符串找到的第一个单词
  • 如果函数没有找到空格,返回整个字符串

如果直接实现这个需求比较繁琐,但我们可以使用字符串切片来简单的进行编写代码

字符串切片是指向字符串中一部分内容的引用:

let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];
println!("{},{}", hello, world); //hello,world
  • 开始索引:起始位置的索引
  • 结束索引:终止位置的下一个索引

关于切片的语法糖:

  • 如果开始索引为0,可省略
  • 如果结束索引为字符串长度,可省略
let s = String::from("hello world");
let hello = &s[..5];
let world = &s[6..];
let whole = &s[..];// &s[0..s.len()]
println!("{},{}", hello, world); //hello,world

注意:

  • 字符串切片的范围索引必须发生在有效的UTF-8边界内
  • 如果尝试从一个多字节的字符串中创建字符串切片,程序将会报错并推出

下面我们将实现之前提到的需求:

fn main() {
    let s = String::from("yes hello world");
    let first_w = first_world(&s);
    println!("{}", first_w); //yes
}

fn first_world(s: &String) -> &str {
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }
    &s[..]
}

字符串字面值是切片

字符串字面值被直接存储在二进制文件中

let s = "nice demo"; //s:&str

变量s的类型是&str,它是一个指向二进制程序特定位置的切片

  • &str是不可变引用,所以字符串的字面值是不可变的

将字符串切片作为参数传递

有经验的开发者会采用&str作为参数类型,因为这样就可以同时接收String和&str类型的参数了:

fn first_word(s:&str)->&str{}
  • 使用字符串切片,直接调用该函数
  • 使用String,可以创建一个完整的String切片来调用该函数

定义函数时使用字符串切片来代替字符串引用会使我们的API更加通用,且不会损失任何功能:

fn main() {
    let s = String::from("yes hello world");
    let first_w = first_world(&s[..]);

    let s1 = "hello demo";
    let first_w1 = first_world(s1);
}

fn first_world(s: &str) -> &str {
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }
    &s[..]
}

其他类型的切片

fn main() {
    let a = [1, 2, 3, 4, 5];
    let slice = &a[1..3];//slice: &[i32]
    println!("{:?}", slice); //[2, 3]
}
相关文章
|
2月前
|
存储 Rust 程序员
Rust中数据类型详解:从整数到字符串
本文将详细解析Rust编程语言中的基本数据类型,包括整数、浮点数、布尔值、字符与字符串。我们将深入探讨每种数据类型的特性、使用场景以及它们在Rust中的实现方式,帮助读者更好地理解和应用这些基础元素。
|
3月前
|
设计模式 Rust JavaScript
【一起学Rust | 设计模式】习惯语法——使用借用类型作为参数、格式化拼接字符串、构造函数
【一起学Rust | 设计模式】习惯语法——使用借用类型作为参数、格式化拼接字符串、构造函数
37 0
|
3月前
|
算法 Java Go
Rust每日一练(Leetday0029) 柱状图、最大矩形、扰乱字符串
Rust每日一练(Leetday0029) 柱状图、最大矩形、扰乱字符串
28 0
Rust每日一练(Leetday0029) 柱状图、最大矩形、扰乱字符串
|
3月前
|
C++ Python Rust
Rust每日一练(Leetday0015) 字符串相乘、通配符匹配、跳跃游戏II
Rust每日一练(Leetday0015) 字符串相乘、通配符匹配、跳跃游戏II
28 0
Rust每日一练(Leetday0015) 字符串相乘、通配符匹配、跳跃游戏II
|
3月前
|
Rust JavaScript 安全
Rust 笔记:Rust 语言中的字符串
Rust 笔记:Rust 语言中的字符串
106 0
|
9月前
|
Rust 程序员 索引
Rust 标准库字符串类型String及其46种常用方法
String是一个可变引用,而&str是对该字符串的不可变引用,即可以更改String的数据,但是不能操作&str的数据。String 类型来自标准库,它是可修改、可变长度、可拥有所有权的同样使用UTF-8编码,且它不以空(null)值终止,实际上就是对Vec的包装,在堆内存上分配一个字符串。由&[u8]表示,UTF-8编码的字符串的引用,字符串字面值,也称作字符串切片。
182 1
|
10月前
|
Rust JavaScript 安全
Rust 笔记Rust 语言中的字符串
本文介绍 Rust 语言中的字符和字符串的用法。
164 0
Rust 笔记Rust 语言中的字符串
|
存储 Rust 程序员
如何理解Rust中的字符串(二)
如何理解Rust中的字符串(二)
|
存储 Rust 索引
【RUST学习日记】第16课 字符串的常用方法(二)
【RUST学习日记】第16课 字符串的常用方法(二)
【RUST学习日记】第16课 字符串的常用方法(二)
|
3天前
|
Rust 安全 程序员