---
title: 字符串与 Path
url: https://doc.liz6.com/rust/10-standard-library-depth/03-strings-and-path
locale: zh
area: rust
tags:
- rust
- 标准库深度
date: 2026-06-30
modified: 2026-06-30
description: '&str 是 UTF-8 保证的字节切片引用(String 是其堆分配版本),不能按 s[0] 索引(因为 UTF-8 一个字符 1-4 字节,O(1) 索引不成立)。OsStr 是平台原生字符串(Unix 上就是字节,Windows 上是 WTF-8),Path 是 OsStr 的路径封装——跨平台文件操作的正确做…'
---

# 字符串与 Path

> `&str` 是 UTF-8 保证的字节切片引用(String 是其堆分配版本),不能按 `s[0]` 索引(因为 UTF-8 一个字符 1-4 字节,O(1) 索引不成立)。`OsStr` 是平台原生字符串(Unix 上就是字节,Windows 上是 WTF-8),`Path` 是 `OsStr` 的路径封装——跨平台文件操作的正确做法是始终用 Path/PathBuf 而非字符串拼接。

## String 与 &str: owned vs borrowed

```rust
let s: String = String::from("hello");  // 堆分配, 可变, owned
let r: &str = "hello";                  // 静态/借用, 不可变
```

`String` = `Vec<u8>` + **UTF-8 validity guarantee**——编译器保证 `String` 的内容始终是有效 UTF-8。可以通过 `into_bytes()` 取出底层 `Vec<u8>`（放弃 UTF-8 保证），也可以通过 `from_utf8()` 从 bytes 构造（返回 `Result`，无效 UTF-8 则 Err）。

## 为什么不能用 s[0]

在 C 中 `s[0]` 返回一个 byte——对 ASCII 没问题，对多语言完全不正确。在 Python 中 `s[0]` 返回第一个 Unicode code point——但 code point 不总是"可见字符"（é 可能是 e + ́，两个 code points）。

Rust 不把这种**有隐藏成本的访问**暴露为索引语法：

```rust
let s = "こんにちは";                  // 5 个字符, UTF-8 中是 15 bytes
// let c = s[0];                      // COMPILE ERROR: no indexing for String
let c = s.chars().nth(2).unwrap();    // 'に' — O(2): 必须跳过前 2 个字符
```

UTF-8 是变长编码：ASCII 字符 1 byte，大多数西欧/中东字符 2 bytes，中日韩字符 3 bytes，emoji 4 bytes。`s[n]` 在 Rust 中不能是 O(1)——所以干脆不提供。程序员必须显式写 `.chars().nth(n)`，承认"这需要扫描"。

## OsStr/OsString: 非 UTF-8 的系统字符串

Unix 上的文件名只是 `[u8]`——可以是任意 bytes，不保证 UTF-8。Windows 上的文件名是 WTF-8（接近 UTF-16）。`OsStr` 是跨平台的抽象——不对内容做 UTF-8 保证，但能安全传递和拼接：

```rust
use std::ffi::OsStr;
use std::path::{Path, PathBuf};

let p = Path::new("/usr/bin");
let parent = p.parent().unwrap();    // /usr
let file = p.file_name().unwrap();   // bin
let full: PathBuf = p.join("subdir").join("file.txt");  // /usr/bin/subdir/file.txt
```

`Path` 只是 `OsStr` 的包装，加了路径专用方法（parent, extension, components, join）。`PathBuf` 是 owned 版本。关键在于：Path 不要求内容转为 String——你可以直接在 Path 上操作，无需先做 UTF-8 检查。

## 参考

- **Rust Book**: Chapter 8.2
- **Rust Reference**: OsStr, Path

*Keywords: String, &str, UTF-8, char, OsStr, Path, PathBuf, indexing, Unicode*
