返回文章列表

文章

关于Rust中的字符串

目录
  1. Below is a structured整合,按“主要字符串类型概览”、“各类型特点”、“使用示例 & 常见转换方式”、“使用场景建议”四大部分展开。
  2. 1. 主要字符串类型概览
  3. 2. 各类型特点
  4. 2.1 &str(字符串切片)
  5. 2.2 String
  6. 2.3 &'static str
  7. 2.4 Cow<str>(Copy‑On‑Write)
  8. 2.5 OsStr / OsString
  9. 2.6 CStr / CString
  10. 2.7 Path / PathBuf
  11. 3. 使用示例 & 常见转换方式
  12. 3.1 &str ↔ String
  13. 3.2 &str ↔ &'static str
  14. 3.3 String ↔ OsString
  15. 3.4 &str ↔ OsStr
  16. 3.5 CStr / CString
  17. 3.6 Path / PathBuf
  18. 4. 使用场景建议

Below is a structured整合,按“主要字符串类型概览”、“各类型特点”、“使用示例 & 常见转换方式”、“使用场景建议”四大部分展开。#

1. 主要字符串类型概览#

类型可变性堆分配UTF‑8 保证生命周期典型用途
&str❌ 不可变❌ 否✅ 是推断(局部借用)只读借用字符串(函数参数/切片)
String✅ 可变✅ 是✅ 是拥有所有权动态构建/拼接/修改
&'static str❌ 不可变❌ 否✅ 是'static字面量/全局常量
Cow<str>✅/❌✅/❌✅ 是借用或拥有懒拷贝通用接口
OsStr / OsString❌/✅❌/✅❌ 平台相关推断/拥有OS 路径/环境变量
CStr / CString❌/✅❌/✅❌ C 风格推断/拥有与 C 接口交互(NUL 结尾)
Path / PathBuf❌/✅❌/✅❌ 平台相关推断/拥有跨平台文件系统路径

2. 各类型特点#

2.1 &str(字符串切片)#

  • 借用引用,不持有数据
  • 通常指向字面量或 String 的一段切片
  • 大小固定(指针 + 长度),高效、零分配

2.2 String#

  • 可变、拥有所有权 的 UTF‑8 堆分配字符串
  • 底层三字段:指针、长度、容量
  • 支持 .push_str(), +, format! 等操作
  • 可用 String::with_capacity(n) 预分配

2.3 &'static str#

  • 指向程序数据段中 永久驻留 的字面量
  • 生命周期贯穿整个程序 ('static)
  • 典型用法:const/static 常量、错误信息

2.4 Cow<str>(Copy‑On‑Write)#

  • 泛型持有:要么借用 &str,要么拥有 String
  • 只有在需要修改时才克隆底层,减少不必要分配
  • 适合库函数或性能敏感场景

2.5 OsStr / OsString#

  • 处理操作系统原生字符串(如文件路径、CLI 参数)
  • Windows 下 UTF‑16LE,Unix 下字节序列
  • 不能保证有效 UTF‑8,需 .to_string_lossy()

2.6 CStr / CString#

  • 与 C 语言交互用,必须 NUL(\0)结尾
  • CString::new() 会检查中间 NUL;CStr 不持有所有权

2.7 Path / PathBuf#

  • 专用于文件系统路径
  • &Path 类似 &strPathBuf 类似 String
  • 自动适配平台分隔符(/ vs \

3. 使用示例 & 常见转换方式#

3.1 &strString#

// &str → String
let s1 = slice.to_string();
let s2 = String::from(slice);
let s3 = slice.to_owned();
let s4: String = slice.into();

// String → &str
let slice1: &str = &s1;
let slice2: &str = s1.as_str();

3.2 &str&'static str#

fn needs_static(s: &'static str) { /*…*/ }
needs_static("I live forever"); // OK
// needs_static(&String::from("temp")); // ❌

3.3 StringOsString#

use std::ffi::OsString;
// String → OsString
let os: OsString = OsString::from(&s);
let os2: OsString = s.clone().into();
// OsString → String
match os.into_string() {
    Ok(s) => println!("{}", s),
    Err(err) => eprintln!("Non-UTF8: {:?}", err),
}

3.4 &strOsStr#

use std::ffi::OsStr;
let os_slice: &OsStr = OsStr::new(slice);
if let Some(u) = os_slice.to_str() {
    println!("{}", u);
} else {
    println!("{}", os_slice.to_string_lossy());
}

3.5 CStr / CString#

use std::ffi::{CStr, CString};
let c_string = CString::new("hello").unwrap();      // String → CString
let c_str: &CStr   = c_string.as_c_str();            // CString → &CStr
let rust_str: &str  = c_str.to_str().unwrap();       // &CStr → &str
let back: String   = c_string.into_string().unwrap(); // CString → String

3.6 Path / PathBuf#

use std::path::{Path, PathBuf};
let pb: PathBuf = PathBuf::from("/etc/passwd");
let p: &Path    = pb.as_path();
if p.exists() { println!("found"); }


4. 使用场景建议#

需求建议类型
只读传参&str
动态拼接、修改String
全局/常量字符串&'static str
返回可能借用也可能拥有Cow<str>
OS 路径/环境变量OsStr/OsString
与 C 接口交互(NUL 结尾)CStr/CString
跨平台文件系统路径Path/PathBuf

通过以上四个维度的梳理,你可以根据「可变性/所有权/生命周期」和「场景需求」灵活选用合适的字符串类型,并在类型间高效地互转。