Z
ZHANK
所有权与借用

String 与 &str

String 堆上可变 vs &str 视图、转换、UTF-8 遍历 chars()/bytes()

String 与 &str

String 是可变的、堆上分配的、拥有的字符串。&str 是对已有字符串的不可变引用——零拷贝视图。

学完本章你将: 掌握 String vs &str 区别、转换、UTF-8 安全遍历。


String vs &str

rust
// String —— 拥有所有权的堆上字符串
let mut s = String::from("Hello");
s.push_str(", World!");
s.push('!');
println!("{}", s);  // "Hello, World!"

// &str —— 字符串切片(引用,不拥有)
let slice: &str = &s;       // 从 String 借用
let literal: &str = "Hi";   // 字面量就是 &str

// 转换
let s = "hello".to_string();       // &str → String
let s = String::from("hello");     // &str → String
let slice = s.as_str();            // String → &str

UTF-8 遍历

rust
let s = String::from("你好世界");

// ⚠️ s[0] 不能直接索引——UTF-8 变长编码
// let c = s[0];  // ❌

// ✅ 按字节
for b in s.bytes() {
    print!("{} ", b);  // 228 189 160 ...
}

// ✅ 按字符(Unicode 标量值)
for c in s.chars() {
    print!("{} ", c);  // 你 好 世 界
}

常用方法

rust
let s = String::from("Hello");

s.len();              // 字节数
s.is_empty();
s.contains("ell");
s.replace("Hello", "Hi");
s.to_uppercase();
s.trim();
s.split(' ');         // 返回迭代器

// 拼接
let s3 = s + " World";  // s 被移动(所有权转移)
let s4 = format!("{} {}", s3, "!!!");  // 不移动