Rust字符串 String 和 &str

138 阅读1分钟

存储:字符串底层存储为 [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 的存在.