2026/5/21 13:18:13
网站建设
项目流程
网站开发做什么简单,做国外网站赚钱,百度网站标题优化,域名解析ip138Rust 提供两种主要字符串类型#xff1a;String#xff08;可变#xff0c;拥有所有权#xff09;和 str#xff08;不可变#xff0c;借用#xff09;。
1. 字符串基础
创建字符串
// 多种创建方式
let s1 String::new(); // 空字符串
let s2 String可变拥有所有权和str不可变借用。1.字符串基础创建字符串// 多种创建方式lets1String::new();// 空字符串lets2初始内容.to_string();// str 转 Stringlets3String::from(Hello);// from 方法lets4字面量.to_owned();// to_owned克隆// 字符串字面量static strletliteral:str我是字面量;更新字符串letmutsString::new();// 追加字符s.push(H);// Hs.push_str(ello);// Hello// 拼接lets1String::from(Hello, );lets2String::from(World!);lets3s1s2;// s1被消耗s3 Hello, World!// 格式拼接lets4format!({}{},Hi, ,Rust!);// Hi, Rust!2.字符串操作访问内容letsString::from(你好世界);// 按字节访问UTF-8编码forbyteins.bytes(){println!({},byte);// UTF-8字节序列}// 按字符访问Unicode标量值forchins.chars(){println!({},ch);// 你, 好, , 世, 界}// 字符迭代器方法letchar_counts.chars().count();// 字符数5letbyte_lens.len();// 字节数15中文3字节/字符切片操作letsString::from(Hello, World!);// 创建字符串切片lethellos[0..5];// Helloletworlds[7..12];// World// 小心必须按字符边界切片// let bad s[0..1]; // 对多字节字符会panic// 安全切片方法ifs.is_char_boundary(3){letslices[0..3];// 安全切片}3.字符串方法查询与检查letsString::from(Hello Rust);// 长度信息letbyte_lens.len();// 字节长度letis_emptys.is_empty();// 是否为空// 包含检查lethas_hellos.contains(Hello);// trueletstartss.starts_with(He);// trueletendss.ends_with(Rust);// true// 查找letfind_idxs.find(Rust);// Some(6)letrfind_idxs.rfind(l);// Some(3)从右向左修改操作letmutsString::from(Hello World);// 替换lets1s.replace(World,Rust);// 新字符串Hello Rusts.replace_range(6..11,Rust);// 原地替换Hello Rust// 删除s.remove(5);// 移除索引5的字符,s.pop();// 移除最后一个字符s.truncate(5);// 截断到前5个字符s.clear();// 清空字符串// 插入s.insert(5,,);// 在索引5插入字符s.insert_str(0,Prefix );// 插入字符串4.字符串转换类型转换// String ↔ strletstringString::from(hello);letstr_slice:strstring;// 自动解引用letowned:Stringstr_slice.to_string();// 数字转字符串letnum_str42.to_string();// 42letfloat_strformat!({:.2},3.14159);// 3.14// 字符串转数字letnum:i3242.parse().unwrap();// 42letnum_result:Resulti32,_42.parse();// Ok(42)字符编码// UTF-8 编码/解码lets Rust;// 包含emoji// 获取UTF-8字节letbytess.as_bytes();// [u8]// 从字节创建需要有效UTF-8letfrom_bytesString::from_utf8(bytes.to_vec());// 处理无效UTF-8letlossyString::from_utf8_lossy(bHello\xFFWorld);// HelloWorld替换无效字节5.字符串格式化format! 宏// 基本格式化letsformat!({} {} {},1,2,3);// 1 2 3// 控制格式letpiformat!(PI: {:.3},3.14159);// PI: 3.142lethexformat!(0x{:X},255);// 0xFFletbinformat!({:b},10);// 1010// 位置参数letsformat!({1} {0},World,Hello);// Hello World// 命名参数letsformat!({name} is {age},nameAlice,age30);其他格式化宏print!(Hello);// 打印不换行println!(World);// 打印换行eprint!(Error);// 标准错误打印eprintln!(Error with newline);letsformat!(Debug: {:?},vec![1,2,3]);// 调试格式letsformat!(Pretty: {:#?},vec![1,2,3]);// 美化调试6.字符串性能优化预分配容量// 避免重复分配letmutsString::with_capacity(100);// 预分配100字节s.push_str(Hello);s.push_str( World);println!(长度: {}, 容量: {},s.len(),s.capacity());// 长度: 11, 容量: 100无需重新分配字符串重用// 复用String缓冲区letmutsString::new();foriin0..10{s.clear();// 清空内容保留容量s.push_str(format!(Item {},i));// 处理s...}使用Cow写时复制usestd::borrow::Cow;fnprocess(input:str)-Cowstr{ifinput.contains(bad){Cow::Owned(input.replace(bad,good))// 需要时克隆}else{Cow::Borrowed(input)// 直接借用}}letresultprocess(hello);// Cow::Borrowed(hello)letresult2process(bad word);// Cow::Owned(good word)7.常用字符串模式字符串分割letsapple,banana,orange;// 按分隔符分割letfruits:Vecstrs.split(,).collect();// [apple, banana, orange]// 保留分隔符letparts:Vecstrs.split_inclusive(,).collect();// [apple,, banana,, orange]// 多分隔符lets2apple, banana; orange;letfruits2:Vecstrs2.split([,,;, ]).collect();// 行分割lettextline1\nline2\r\nline3;letlines:Vecstrtext.lines().collect();字符串修剪lets Hello Rust! \n;lettrimmeds.trim();// Hello Rust!移除两端空白letleft_trimmeds.trim_start();// Hello Rust! \nletright_trimmeds.trim_end();// Hello Rust!// 自定义修剪字符lets2***Hello***;lettrimmed2s2.trim_matches(*);// Hello大小写转换letsHello Rust;letuppers.to_uppercase();// HELLO RUSTletlowers.to_lowercase();// hello rust// 首字母大写fncapitalize(s:str)-String{letmutcharss.chars();matchchars.next(){NoneString::new(),Some(first)first.to_uppercase().chain(chars).collect(),}}letcapcapitalize(hello);// Hello8.字符串与集合字符串向量// 字符串集合letwordsvec![hello,world,rust].into_iter().map(|s|s.to_string()).collect::VecString();// 连接字符串letsentencewords.join( );// hello world rust// 拼接多个字符串letconcatenated[foo,bar,baz].concat();// foobarbaz字符处理letsHello 世界;// 字符统计letchar_counts.chars().count();// 7letgrapheme_counts.chars().count();// 注意可能不是字形簇数// 字符位置ifletSome(pos)s.char_indices().find(|(_,ch)|*ch世).map(|(i,_)|i){println!(世在位置 {},pos);// 输出位置}9.字符串与I/O文件读写usestd::fs;usestd::io::{self,Write,BufRead};// 读取文件为字符串letcontentfs::read_to_string(file.txt)?;// 写入字符串到文件fs::write(output.txt,Hello World)?;// 逐行读取letfilefs::File::open(file.txt)?;letreaderio::BufReader::new(file);forlineinreader.lines(){letlineline?;println!({},line);}用户输入usestd::io;letmutinputString::new();println!(请输入:);io::stdin().read_line(mutinput)// 读取一行.expect(读取失败);lettrimmedinput.trim();// 移除换行符println!(你输入了: {},trimmed);10.字符串最佳实践选择指南函数参数优先使用str而非String返回类型需要所有权时用String否则考虑Cowstr性能敏感预分配容量避免重复分配国际文本使用chars()而非字节索引常见错误避免// ❌ 错误多字节字符切片// let s 你好;// let slice s[0..1]; // panic// ✅ 正确使用字符迭代lets你好;ifletSome(first_char)s.chars().next(){println!(首字符: {},first_char);}// ❌ 避免不必要的String分配fnbad_greeting(name:String)-String{format!(Hello, {},name)// 可以接受str}// ✅ 改进使用str参数fngood_greeting(name:str)-String{format!(Hello, {},name)}String vs str 总结特性Stringstr所有权拥有数据借用数据可变性可变不可变内存位置堆栈、堆或静态内存大小动态编译时已知性能有分配开销无分配开销核心原则需要修改或拥有字符串时使用String只读引用时使用str函数参数优先接受str以兼容两者使用to_string()或into()进行必要转换Rust的字符串设计确保了内存安全和UTF-8编码正确性虽然增加了复杂性但提供了强大的安全保证。