存储:字符串底层存储为 [u8]
编码: String 和 &str 都是 UTF-8编码 通常,每个字符占用一个字节,每个汉字占用三个字节,以下代码运行时会崩溃:
let s = "中国人";
let a = &s[0..2];
因为索引2 落在非字符边界的位置。
是否可变: String可变,&str不可变。对此的解释为,String本就是为了支持变长文本的,其内存分配在堆上,大小在运行时才知道;str则是编译阶段就确定大小的,最终硬编码入代码,以达到快速而高效的使用。
String 和 &str 的转换
// String -> &str
&String;
&String[..];
String.as_str();
// &str -> String
String::from(&str);
&str.to_string();
// ---- 单转偷懒示例 ----
// 宏
macro_rules! to_string {
($s:expr) => {
String::from($s)
};
}
// 发散函数
fn to_string(x: impl Into<String>) -> String {
x.into()
}
字符串方法
// 追加
String.push(char);
String.push_str(&str);
// 插入
String.insert(index, char);
String.insert_str(index, &str);
// 替换(返回新字符串)
String.replace(&str1, &str2);
String.replacen(&str1, &str2, replaceCount);
// 替换(操作原字符串)
String.replace_range(range, &str)
// 删除
String.pop(); // 返回移除的
String.truncate(index); // 删除包含index以及之后的
String.remove(index); // 返回删除位置的
String.clear(); // 清空 truncate(0)
// 拼接
String + &str(次序不能改变, `std::string` 标准库中的 [`add()`](https://doc.rust-lang.org/std/string/struct.String.html#method.add) 方法)
(emmmm, 确实有点恶心,不过语言机制就这样子,具体要看两个类的底层实现了。)
// 常用已实现了的宏
format!("{}{}", a, b)
// 遍历
for c in &str.chars() {
println!("{}", c);
}
for b in &str.bytes() {
println!("{}", b);
}
str 是基本类型,相关 trait 实现位于 core,String 是标准库类型,位于 alloc。alloc 依赖 core,在编译 core 时看不到 String 的存在.