【编程】Rust语言入门第4篇 字符串

news/2024/4/23 3:13:34

Rust 中的字符是 Unicode 类型,因此每个字符占据 4 个字节内存空间,但字符串不一样,字符串是 UTF-8 编码,也就是字符串中的字符所占的字节数是变化的(1 - 4)。
常见的字符串有两种:

  1. str,通常是引用类型,&str,即字符串字面常量,字符串切片。
  2. std::string::String
    类型&str的变量是被硬编码的,快速而高效,但不可变;类型String,是可设可变的,它是在堆上的变量,如何管理内存,有的语言用垃圾回收机制(Garbage Collection),标记使用情况并自动清理;而Rust不愿意用GC,既要高性能,又要高安全性,提出变量离开作用域即自动释放其占用的内存,比GC思路更妙。
    C语言中清理内存的函数free,要被手动调用;Rust中则是drop(),Rust自动调用。
    C++中的Resoure Acquisition Is Initialization,RAII模型。

两种字符串类型互转

&strString:

let a = String::from("hello, world");
"hello, world".to_string();

String&str,引用即可

fn main() {let s = String::from("hello,world!");say_hello(&s);say_hello(&s[..]);say_hello(s.as_str());
}fn say_hello(s: &str) {println!("{}",s);
}

除上述两种类型,Rust标准库还有其他类型的字符串。

字符串不能被直接索引

Rust字符串不允许索引操作。由于不同字符占用字节数不等,考虑操作时间复杂度不能实现O(1)。

//三个字节
let a = "中国人";
//一个字节
let b = "Chinese";

Rust字符串虽然不能索引但可以切片(slice),类似Python等语言中的切片概念。

fn main() {let my_name = "kirk zhang";let first_name = &my_name[0..4];let last_name = &my_name[5..10];println!("{}",first_name);println!("{}",last_name);greet(String::from(my_name));// 尝试my_name[0]报错,不过可以用.chars().nth或.bytes()来实现println!("can str be indexed {:?}",my_name.chars().nth(0));
}fn greet(name: String){println!("hello {}", name);
}

小心字符串切片

注意字符串切片是按字节来的哦,而Rust字符串是UTF-8协议格式,一般1个字符1个字节,但1个中文字符占3个字节;如果切片起止不在字符边界,则有异常。

fn main(){let f = "中国人";let f1 = &f[0..5];println!("watch out, what you got {}",f1);
}

提示:thread ‘main’ panicked at ‘byte index 5 is not a char boundary; it is inside ‘国’ (bytes 3…6) of 中国人’, src/main.rs:10:15
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

字符串的操作

替换

replace(要被替换的子串,新字符串),返回结果字符串。

    let word = String::from("rust");let new_word = word.replace("r","R");println!("{}", new_word);

插入

insert(位置索引,字符)、insert_str(位置索引,字符串):变量本身变化,声明时要mut。

    let word = String::from("rust");let mut new_word = word.replace("r","R");new_word.insert_str(0, "I love ");println!("{}", new_word);

追加

push(字符)
push_str(字符串)

    let word = String::from("rust");let mut new_word = word.replace("r","R");new_word.insert_str(0, "I love ");new_word.push('!');println!("{}", new_word);   

连接

++= 调用了String的add(self,&str)方法,其定义要求+后面的参数为字符串字面常量,返回String类型。
或用format! ,适用于 String 和 &str 。format! 的用法与 println! 的用法类似。

let a1 = String::from("tic");
let a2 = String::from("tac");
let a3 = String::from("toe");// 经过下面一行后,a1被释放了,不能再使用!a2、a3依然存在。
let s = s1 + "-" + &s2 + "-" + &s3;

删除

有4个方法,pop()、remove(索引位置)、truncate(起始位置)、clear()
注意删除字符串的索引必须是字符串中字符的边界,否则错误。

fn main() {let mut string_remove = String::from("测试remove方法");println!("string_remove 占 {} 个字节",std::mem::size_of_val(string_remove.as_str()));// 删除第一个汉字string_remove.remove(0);// 下面代码会发生错误// string_remove.remove(1);// 直接删除第二个汉字// string_remove.remove(3);dbg!(string_remove);
}

字符串的字符与字节

例,

   for c in "中国人".chars() {println!("{}", c);}for b in "中国人".bytes() {println!("{}", b);}

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

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

相关文章

华为配置直连三层组网直接转发示例

华为配置直连三层组网直接转发示例 组网图形 图1 配置直连三层组网直接转发示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件扩展阅读 业务需求 企业用户接入WLAN网络,以满足移动办公的最基本需求。且在覆盖区域内移动发生漫游时&#xff…

计算机设计大赛 深度学习OCR中文识别 - opencv python

文章目录 0 前言1 课题背景2 实现效果3 文本区域检测网络-CTPN4 文本识别网络-CRNN5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习OCR中文识别系统 ** 该项目较为新颖,适合作为竞赛课题方向,…

【PCIE709-F】基于复旦微JFM7VX690T80 FPGA的全国产化8通道光纤双FMC接口数据处理平台

板卡概述 PCIE709-F是一款基于上海复旦微电子的28nm 7系列FPGA JFM7VX690T80的全国产化8通道光纤双FMC接口数据预处理平台,该板卡采用复旦微的高性能7系列FPGA作为实时处理器,实现4路10G SFP光纤以及1路QSFP通信接口、实现1路X8 PCIE数据传输的功能。板载…

高中数学:一元二次函数根的分布问题

一、基本性质 例题: 二、根的分布问题 已知两根,求参数取值范围的问题,就是根的分布问题 1、韦达定理 针对题目中根与0点比较的问题 例如: 2、画图法 解决根在某个特定范围内时,求参数范围的问题。 例题1&…

ubuntu18下安装搜狗拼音输入法并配置

打开搜过拼音输入法安装指导的官网:https://shurufa.sogou.com/linux/guide 按照ubuntu20的安装方法在ubuntu18上面进行安装和配置(如下图是开头的部分,之前的不用看,按照前面的配置方法不会切换到中文,因为没有删除i…

【lesson51】信号之信号处理

文章目录 信号处理可重入函数volatileSIGCHLD信号 信号处理 信号产生之后,信号可能无法被立即处理,一般在合适的时候处理。 1.在合适的时候处理(是什么时候?) 信号相关的数据字段都是在进程PCB内部。 而进程工作的状态…