结论:String 是拥有所有权的堆分配字符串(可增长、可修改);&str 是对某段 UTF-8 文本的借用视图(字符串切片),本身不拥有数据。选型原则:存储/拥有数据用 String,函数参数读数据用 &str,返回新建内容返回 String

展开:String 内部是 Vec<u8> 的封装并保证 UTF-8;&str 是胖指针(指针+长度),可指向堆上 String 的数据、字符串字面量('static)或其他缓冲。String 通过 &ss.as_str() 可无损降级为 &str,所以参数用 &str 能同时接受 String、字面量和切片,API 最通用。易错点:①不要用 &String 作参数(&str 更灵活且少一层间接);②str 是未定型(unsized),只能以 &str/Box<str> 形式存在;③不支持 s[i] 按字节索引(UTF-8 变长编码),需用 chars()/bytes()。追问方向:什么时候用 Cow<'_, str>?当"多数情况借用、少数情况需要修改并拥有"时可避免不必要分配。

fn shout(s: &str) -> String { s.to_uppercase() }
let owned = String::from("hi");
let _ = shout(&owned);    // &String 自动 deref 为 &str
let _ = shout("literal"); // 字面量本身是 &'static str