Rust字符串详解

文章目录

字符串切片

我们所熟知的由双引号括起来的字符串,在Rust中只是个字符串切片,又叫字符串字面值。这种类型一旦创建,则不可更改。但支持索引,从切片中索引出来的内容,仍是切片,其基本语法有二

  • st..ed 表示从第st个字符开始,到第ed-1个字符为止
  • st..=ed 表示从第st个字符开始,到第ed个字符为止

示例如下

rust 复制代码
fn main(){
    let s = "micro cold";
    let a = s.to_string();
    println!("{}", &s[1..4]);
    println!("{}", &a[1..=4]);
}

输出为

icr

icro

String

String是Rust标准库实现的结构体,其内容、长度均可更改,Rust提供了如下三种创建字符串的方法,其中两种基于字面量。

  • 创建空字符串 let e = String::new()
  • 创建长度为N的字符串 let c = String::with_capacity()
  • 从字面量创建字符串 let s = String::from("rust")
  • 调用字面量的内置方法 let t = "rust".to_string()

其中,new, from, with_capacity为String结构体的关联函数,to_string则是字面量的成员方法。

String类型并不支持索引,但通过&可以获取其对应的字面量,从而支持字面量的切片操作。

此外,非常诡异地,Rust对加号进行了运算符重载,但其左侧第一个值必须是字符串,而其他值则必须为字面量。示例如下

rust 复制代码
fn main(){
    //let s = "micro" + "cold";  //报错
    let s = "micro cold";
    let a = s.to_string();
    println!("{}", a + "!");    // 不报错
    //println!("{}", a + a);    // 报错
    //println!("{}", a + &a);   // 报错,但原因是所有权
}

输出为

micro cold!

迭代方法

String结构体中封装了许多迭代器,包括

  • .chars() 遍历字符串的Unicode字符
  • .bytes() 遍历字符串的字节序列
  • .split© 根据c对字符串进行拆分,并遍历
  • .split_whitespace() 根据空格对字符串进行拆分,并遍历

此外,对于多行文本,还有.lines,可将字符串按行分割为迭代器,每个元素都是一行文本。

rust 复制代码
fn main(){
    //let s = "micro" + "cold";  //报错
    let s = "micro cold".to_string();
    for c in s.chars(){
        println!("{}", c);
    }
    for b in s.bytes(){
        println!("{}", b);
    }
    println!("====split by o");
    for o in s.split("o"){
        println!("{}", o);
    }
    println!("====split_whitespace");
    for w in s.split_whitespace(){
        println!("{}", w);
    }
}

输出结果如下

m
i
c
r
o

c
o
l
d
109
105
99
114
111
32
99
111
108
100
====split by o
micr
 c
ld
====split_whitespace
micro
cold

除了上述迭代用法,Rust字符串还提供了返回元组的拆分函数

  • split_at():将字符串分成两个部分,在指定的位置进行分割。
  • split_off():从字符串的指定位置分离出一个子字符串,并返回新的 String 对象。

基础字符串方法

除了clone这种深拷贝必备方法外,String还实现了诸多功能,如下表所示

属性 长度 len(), 字节数 capacity
判定 是否为空 is_empty()
大小写转换 转小写 to_lowercase();转大写 to_uppercase()
类型转换 转字节数组 as_bytes();转字节向量into_bytes(); 转可变切片 as_mut_str();转切片as_str()
删除空格 首空格trim_start();尾空格trim_end();首尾空格trim()
关系 包含关系contain(), 相等eq(),
首尾判断 以某字符串开头starts_with();以某字符串结尾ends_with()

这些方法的调用形式均为s.xxx(),示例如下

rust 复制代码
fn main(){
    let mut s = "micro cold".to_string();
    println!("len:{}", s.len());
    println!("uppercase:{}", s.to_uppercase());
}

结果如下

rs 复制代码
len:10
uppercase:MICRO COLD 

容量操作

字符串为了实现内容可变,必须要预留一定的空间,为此Rust提供了一些函数

  • reserve():为字符串新增一些空间
  • shrink_to_fit():将字符串的容量缩小到它所包含的内容所需的最小值。
  • shrink_to():将字符串的容量缩小到指定下限。如果当前容量小于下限,或者大于当前值,则什么也不做。
rust 复制代码
fn main(){
    let mut s = "micro cold".to_string();
    println!("original capacity = {}", s.capacity());
    s.reserve(10);
    println!("after reserve = {}", s.capacity());
    s.shrink_to_fit();
    println!("fit capacity = {}", s.capacity());
    s.shrink_to(25);
    println!("fit to 25 = {}", s.capacity());
}

效果如下

rust 复制代码
original capacity = 10
after reserve = 20
fit capacity = 10
fit to 25 = 10

增删改查

String是可变字符串,故而提供了诸多增加、删除、改动的操作

类别 方法
弹出与追加 追加字符push;追加字符串push_str;弹出最后一个字符pop
删除 清空clear;截短truncate;删除某位置remove 匹配删除remove_matches
插入 插入字符insert;插入字符串insert_str
替换 匹配替换replace;位置替换replace_range;
匹配 从左查找find;从右查找rfind,均返回第一个匹配的位置

下面对上述方法进行测试

rust 复制代码
fn main(){
    let mut s = "micro cold".to_string();
    s.push('a');
    println!("push('a') -> {}", s);
    s.push_str("bcd");
    println!("push_str(\"bcd\") -> {}", s);
    s.truncate(10);
    println!("truncate(3) -> {}", s);
    s.remove(1);
    println!("remove(1) -> {}", s);
    s.insert(1, 'i');
    println!("insert(1, 'i') -> {}", s);
    s.insert_str(0, "hello ");
    println!("insert_str(0, \"hello \") -> {}", s);
    s.replace_range(0..5, "Hola");
    println!("replace_range(0..5, \"Hola\") -> {}", s);
    println!("s.replace(\"Hola\", \"你好\") -> {}", 
        s.replace("Hola", "你好"));
}

测试结果如下

rust 复制代码
push('a') -> micro colda
push_str("bcd") -> micro coldabcd
truncate(3) -> micro cold
remove(1) -> mcro cold
insert(1, 'i') -> micro cold
insert_str(0, "hello ") -> hello micro cold
replace_range(0..5, "Hola") -> Hola micro cold
s.replace("Hola", "你好") -> 你好 micro cold
相关推荐
SpongeG20 分钟前
数据结构第三周做题总结_链表
数据结构·算法·链表
小珑也要变强22 分钟前
队列基础概念
c语言·开发语言·数据结构·物联网
醉竺26 分钟前
【高阶数据结构】二叉搜索树的插入、删除和查找(精美图解+完整代码)
数据结构
little redcap2 小时前
第十九次CCF计算机软件能力认证-乔乔和牛牛逛超市
数据结构·c++·算法
LvManBa6 小时前
Vue学习记录之六(组件实战及BEM框架了解)
vue.js·学习·rust
凡人的AI工具箱6 小时前
AI教你学Python 第11天 : 局部变量与全局变量
开发语言·人工智能·后端·python
是店小二呀6 小时前
【C++】C++ STL探索:Priority Queue与仿函数的深入解析
开发语言·c++·后端
manba_6 小时前
leetcode-560. 和为 K 的子数组
数据结构·算法·leetcode
canonical_entropy6 小时前
金蝶云苍穹的Extension与Nop平台的Delta的区别
后端·低代码·架构
汉字萌萌哒7 小时前
【2022 CCF 非专业级别软件能力认证第一轮(CSP-J1)入门级 C++语言试题及解析】
数据结构·c++·算法