Rust 中通常说的字符串指的是:String 和 &str(字符串字面值、或者叫字符串切片)这两种类型。str是rust中基础字符串类型,String是标准库里面的类型。Rust 中的字符串本质上是:Byte的集合(Vec<u8>)
基础类型转换成字符串
let one = 1.to_string(); // 整数到字符串
let float = 1.3.to_string(); // 浮点数到字符串
let slice = "slice".to_string(); // 字符串切片到字符串
String 的拼接
操作 | 解释 |
---|---|
push_str()方法 | 把一个字符串切片附加到 String |
push() 方法 | 把单个字符附加到 String |
+ | 连接字符串 |
format!() | 灵活拼接多个字符串 |
示例:
fn main() {
let mut s1 = String::from("He");
s1.push_str("llo, ");
let mut s2 = String::from("world");
s2.push('!');
//等号后面的第一个变量取得所有权,其他加号后面的都是变量的引用
let s3 = s1 + &s2;
println!("{}", s3);
//这行代码报错,s1的所有权已经转移
//println!("{}", s1);
println!("{}", s2);
let c1 = String::from("we");
let c2 = String::from("need");
let c3 = String::from("to");
let c4 = String::from("use");
let c5 = String::from("format()!");
//使用format,不会取得任何参数的所有权
let s4 = format!("{} {} {} {} {}", c1, c2, c3, c4, c5);
println!("{}", s4);
}
Rust中字符串不支持索引语法访问,原因:
- Sting里面的字符索引并不总是能对应到一个有效的Unicode标量值。
- 索引操作应消耗一个常量时间(O(1)),而 String 无法保证,需要遍历所有内容,来确定有多少个合法的字符。
示例:
fn main() {
// 梵文书写的印度语单词
let hello = String::from("नमस्ते");
//以字节的形式输出
//输出结果:224 164 168 224 164 174 224 164 184 224 165 141 224 164 164 224 165 135
for i in hello.bytes() {
print!(" {}", i)
}
println!();
//以Unicode标量值的形式输出
//输出结果: न म स ् त े%
for i in hello.chars() {
print!(" {}", i)
}
//以字形簇的形式输出,标准库不提供,可以在crates.io网站上找第三方库
}
使用注意事项
使用字符串split切割的时候,传递的参数必须是&str类型,可以是单个字符,也可以是多个字符,切割完之后,得到的结果需要转为集合才可以获取到的想要的数据。
按字符切割
fn main() {
let text = "apple,banana,cherry";
let fruits: Vec<&str> = text.split(',').collect();
println!("{:?}", fruits); // Output: ["apple", "banana", "cherry"]
}
按字符串分割
要按字符串模式而不是单个字符进行分割,您可以split轻松地使用该方法。
let text = "apple>>banana>>cherry";
let fruits: Vec<&str> = text.split(">>").collect();
println!("{:?}", fruits); // Output: ["apple", "banana", "cherry"]
用闭包分割
对于更复杂的拆分逻辑,您可以传递一个闭包来split确定拆分逻辑。
fn main() {
let text = "apple1banana2cherry";
let fruits: Vec<&str> = text.split(|c: char| c.is_numeric()).collect();
println!("{:?}", fruits); // Output: ["apple", "banana", "cherry"]
}
split_whitespace
split_whitespace方法是一种按空格分割字符串的便捷方法。
fn main() {
let text = "apple banana cherry";
let fruits: Vec<&str> = text.split_whitespace().collect();
println!("{:?}", fruits); // Output: ["apple", "banana", "cherry"]
}
split_once
有时,您可能希望在模式第一次出现时将字符串分成两部分。该split_once方法非常适合于此。
fn main() {
let text = "apple,banana,cherry";
if let Some((first, rest)) = text.split_once(',') {
println!("First fruit: {}", first); // Output: "First fruit: apple"
println!("The rest: {}", rest); // Output: "The rest: banana,cherry"
}
}
拆分并保留结果中的模式
Rust 还允许拆分,而不会忽略结果子字符串中的模式。split_inclusive方法在分割后将模式包含在子串中
fn main() {
let text = "apple,banana,cherry";
let fruits: Vec<&str> = text.split_inclusive(',').collect();
println!("{:?}", fruits); // Output: ["apple,", "banana,", "cherry"]
}
处理空子字符串
请注意,如果存在连续的分割模式,split方法将包含空子字符串。
fn main() {
let text = "apple,,banana,,,cherry";
let fruits: Vec<&str> = text.split(',').collect();
println!("{:?}", fruits); // Output: ["apple", "", "banana", "", "", "cherry"]
}
为了避免空字符串,您可以使用filter排除它们。
fn main() {
let text = "apple,,banana,,,cherry";
let fruits: Vec<&str> = text.split(',').filter(|&s| !s.is_empty()).collect();
println!("{:?}", fruits); // Output: ["apple", "banana", "cherry"]
}