rust-stdlib について
Rust 開発者向けに、標準ライブラリ API の選択と組み合わせを案内するスキルです。コレクション、ポインター、文字列、I/O、イテレーター、並行処理の選択を扱います。
主な機能
- 01コレクションとスマートポインターの選択
- 02文字列型とパス型の選択
- 03Option と Result の連鎖処理
- 04I/O トレイトとイテレーターパターンの選択
- 05標準ライブラリの並行処理プリミティブ
活用シーン
- 01検索や順序付けに使うコレクションの選択
- 02所有権と内部可変性の型の選択
- 03ファイル I/O とイテレーターパイプラインの構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ full-stack-skills/ rust-skills --skill rust-stdlibインストール後、Claude Code で/rust-stdlibを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlexamples/golden-stdlib/Cargo.lockCargo.tomlexamples/golden-stdlib/src/lib.rsreferences/collections.mdinterior-mutability.mdio-streams.mditerators.mdoption-result-combinators.mdprocess-and-fs.mdsmart-pointers.mdstd-concurrency.mdstd-module-index.mdstring-types.md詳細
Rust 標準ライブラリ — API の選択と組み合わせ
権威ある参照先:Rust 標準ライブラリ — 標準的なリファレンスです。モジュールの全体像については、
references/std-module-index.mdを参照してください。
このスキルが扱うのは std API の選択と組み合わせです。どのコレクション、スマートポインター、文字列型、I/O トレイト、イテレーターパターンを使うかを扱います。言語のセマンティクス(rust-stable)、非同期ランタイム(rust-concurrency)、アプリケーション層の関心事(ドメインスキル)は扱いません。
対応範囲
✅ 得意分野
- 適切なコレクションの選択(HashMap と BTreeMap、Vec、VecDeque、LinkedList、BinaryHeap の比較)
- 適切なスマートポインターの選択(Box、Rc、Arc、RefCell、Mutex、OnceLock の比較)
- 適切な文字列型の選択(String、&str、OsString、PathBuf、Cow の比較)
- 内部可変性プリミティブの選択(Cell、RefCell、OnceCell、OnceLock、LazyLock の比較)
- Option/Result のコンビネーターをつなげた処理の設計(map、and_then、unwrap_or_else、ok_or、transpose)
- I/O トレイトの選択(Read、Write、BufRead、Seek、AsyncRead の比較)
- イテレーターパターンの選択(iter、into_iter、所有権を持つイテレーター、遅延評価と collect の比較)
- std の並行処理プリミティブの使用(thread、mpsc、barrier、Once、スコープ付きスレッド)
- 時刻 API の選択(Duration、Instant、SystemTime、TryFromFloat の比較)
- クロスプラットフォームのパス処理(Path と PathBuf、fs、env、process::Command)
⚠️ 前提条件
- Rust の所有権とライフタイム —
rust-stableを参照 - Cargo とプロジェクト構成 —
rust-cargo-build、rust-workspaceを参照
❌ 対象外
- 非同期ランタイム(Tokio、async-std)→
rust-concurrency - 言語のセマンティクス(所有権、トレイト、ライフタイム)→
rust-stable - アプリケーション層の関心事(CLI、ウェブ、データベース)→ ドメインスキル
- Unsafe と FFI →
rust-unsafe-ffi
データのプライバシー
このスキルは、ユーザーデータを収集、保存、送信しません。
パート 1:コレクション
判断ツリー
Need a collection?
│
├─ Key-value lookup?
│ ├─ Order doesn't matter, fast lookup → HashMap<K, V>
│ ├─ Need sorted iteration / range queries → BTreeMap<K, V>
│ └─ Tiny (<20 entries), linear scan OK → Vec<(K, V)> with .iter().find()
│
├─ Sequence?
│ ├─ Append/pop from end → Vec<T>
│ ├─ Push/pop from both ends → VecDeque<T>
│ ├─ Insert/remove from middle frequently → LinkedList<T> (rare; usually Vec is better)
│ └─ Priority queue / always-min-first → BinaryHeap<T>
│
├─ Set?
│ ├─ Fast membership, no order → HashSet<T>
│ └─ Sorted iteration → BTreeSet<T>
│
└─ No collection needed — use Vec<T>
クイックリファレンス
| 型 | 順序 | 検索 | 挿入 | 用途 |
|---|---|---|---|---|
Vec<T> | 挿入順 | 値で O(n)、インデックスで O(1) | push の償却 O(1) | 標準的なシーケンス |
VecDeque<T> | 挿入順 | 先頭/末尾で O(1) | 先頭/末尾で O(1) | キュー、スライディングウィンドウ |
LinkedList<T> | 挿入順 | O(n) | カーソルを使えば任意の位置で O(1) | ほとんど使いません。Vec を優先してください |
BinaryHeap<T> | 優先度順 | 先頭要素の参照で O(1) | push/pop で O(log n) | 優先度付きキュー |
HashMap<K,V> | なし | 平均 O(1) | 平均 O(1) | 高速な検索、順序なし |
BTreeMap<K,V> | ソート済み | O(log n) | O(log n) | 順序付きキー、範囲検索 |
HashSet<T> | なし | 平均 O(1) | 平均 O(1) | 要素の所属確認 |
BTreeSet<T> | ソート済み | O(log n) | O(log n) | ソート済み要素の所属確認 |
メモリー確保の挙動、ハッシャーの選択(BuildHasherDefault/FxHashMap)、Entry API のパターンについては、references/collections.md を参照してください。
Entry API — 二重検索を回避
use std::collections::HashMap;
let mut counts: HashMap<&str, u32> = HashMap::new();
for word in text.split_whitespace() {
*counts.entry(word).or_insert(0) += 1; // single hash, no double lookup
}
パート 2:スマートポインター
判断ツリー
Need shared/indirected ownership?
│
├─ Single owner, heap-allocated → Box<T>
│
├─ Multiple readers, single thread → Rc<T>
│ └─ Need to mutate through shared ref → Rc<RefCell<T>>
│
├─ Multiple readers, multiple threads → Arc<T>
│ └─ Need to mutate through shared ref → Arc<Mutex<T>> or Arc<RwLock<T>>
│
├─ Need lazy one-time init → OnceLock<T> (sync) or once_cell::Lazy
│
└─ Need interior mutability (no shared ownership)?
├─ Copy type, simple → Cell<T>
├─ Non-Copy, complex → RefCell<T> (single thread)
└─ Multi-thread → Mutex<T> or RwLock<T>
クイックリファレンス
| 型 | 所有権 | スレッドセーフ | 可変性 | 用途 |
|---|---|---|---|---|
Box<T> | 単独 | はい | 直接(所有) | ヒープ確保、再帰型 |
Rc<T> | 共有 | いいえ | 不変のみ | 参照カウント、シングルスレッド |
Arc<T> | 共有 | はい | 不変のみ | アトミックな RC、マルチスレッド |
Cell<T> | 単独 | いいえ | 内部(Copy のみ) | 単純な可変状態 |
RefCell<T> | 単独 | いいえ | 内部(実行時に借用を検査) | 共有参照を介した変更 |
Mutex<T> | 単独 | はい | 内部(ロック) | 共有可変状態、同期 |
RwLock<T> | 単独 | はい | 内部(読み書きロック) | 多数の読み取り、少数の書き込み |
OnceLock<T> | 単独 | はい | 一度だけ初期化 | 遅延初期化グローバル、std::sync::OnceLock |
LazyLock<T> | 単独 | はい | 一度だけ初期化、透過的なデリファレンス | 定数に近いグローバル(Rust 1.80 以降) |
トレードオフ、drop の順序、循環参照に使う Weak<T> については、references/smart-pointers.md を参照してください。
パート 3:文字列型
判断ツリー
Working with text?
│
├─ Function parameter → &str (always)
├─ Owned, mutable, UTF-8 → String
├─ Borrowed, UTF-8, with mixed owned/borrowed → Cow<'a, str>
├─ OS path (Windows/Unix native) → OsString (owned) / OsStr (borrowed)
├─ Filesystem path → PathBuf (owned) / Path (borrowed)
└─ Bytes that might not be UTF-8 → Vec<u8> / &[u8]
クイックリファレンス
| 種類 | エンコーディング | 所有するか | 用途 |
|---|---|---|---|
&str | UTF-8 | いいえ | 関数のパラメーター、文字列リテラル |
String | UTF-8 | はい | 所有する可変の UTF-8 テキスト |
OsString/OsStr | プラットフォームネイティブ | はい/いいえ | 環境変数、プロセス引数 |
PathBuf/Path | プラットフォームネイティブ | はい/いいえ | ファイルシステムのパス |
Cow<'a, str> | UTF-8 | 場合による | 可能な場合はゼロコピー、必要な場合は所有 |
Vec<u8>/&[u8] | バイト列 | はい/いいえ | バイナリデータ、非 UTF-8 |
変換(.to_string() と .to_owned() と .into())、Cow の使い方、&str のスライスの安全性(is_char_boundary)については、references/string-types.md を参照してください。
パート 4:内部可変性
Cell、RefCell、OnceCell の比較
use std::cell::{Cell, RefCell, OnceCell};
// Cell: only for Copy types, no borrow checking
let counter = Cell::new(0);
counter.set(counter.get() + 1);
// RefCell: for non-Copy types, runtime borrow check (panics on double borrow)
let cache = RefCell::new(HashMap::new());
cache.borrow_mut().insert("k", 42);
// OnceCell: one-time initialization
static CONFIG: OnceCell<Config> = OnceCell::new();
let cfg = CONFIG.get_or_init(|| Config::load());
| 型 | Sync か | 用途 |
|---|---|---|
Cell<T> | いいえ | Copy 型のみ、簡単な変更 |
RefCell<T> | いいえ | Copy 以外の型、単一スレッド |
OnceCell<T> | いいえ | 1 回限りの遅延初期化 |
OnceLock<T> | はい | 1 回限りの遅延初期化、マルチスレッド(std 1.70+) |
LazyLock<T> | はい | 透過的な遅延初期化(std 1.80+) |
パニック安全性(RefCell の二重借用)、Cell と RefCell の選択、マルチスレッド向けの Atomic* については、references/interior-mutability.md を参照してください。
パート 5:Option と Result のコンビネーター
Option のコンビネーター
// map: transform inner value
name.map(|n| n.to_uppercase()) // Option<String>
// and_then: chain fallible operations
id.and_then(|i| db.lookup(i)) // Option<User>
// unwrap_or / unwrap_or_else: provide default
port.unwrap_or(8080)
port.unwrap_or_else(|| env::var("PORT").unwrap_or("8080").parse().unwrap())
// ok_or / ok_or_else: convert Option to Result
user.ok_or(Error::NotFound)?
user.ok_or_else(|| Error::UserMissing(id))?
// filter, is_some, is_some_and
age.filter(|&a| a >= 18)
opt.is_some_and(|x| x > 0)
// transpose: swap Option<Result> → Result<Option>
let x: Result<Option<i32>, _> = Some("5").parse::<i32>().map(Some);
Result のコンビネーター
// ? for propagation (prefer over explicit match)
fn load() -> Result<Config, Error> { Ok(parse(file_read()?)?) }
// map_err: convert error type
file_read().map_err(|e| Error::Io(e))?
// map: transform success value
parse(s).map(|n| n * 2)
// and_then: chain fallible
validate(input).and_then(process)
// or_else / or: fallback on error
primary.or_else(|_| fallback())
よく使われるパターン
| パターン | コード |
|---|---|
| パースを試み、デフォルト値にフォールバックする | s.parse().unwrap_or(default) |
| エラー時に早期リターンする | let x = result?; |
| Option を Result に変換する | opt.ok_or(Error::Missing)? |
| すべての Result を収集する | results.collect::<Result<Vec<_>, _>>() |
| すべて試し、最初に成功したものを返す | `opts.into_iter().find_map( |
コンビネーターの全一覧とリファクタリングのパターンについては、references/option-result-combinators.md を参照してください。
パート 6:I/O ストリーム
トレイト階層
Read ────┐
├─ BufRead (adds buffering, lines())
Write ───┘
Seek (random access)
選び方
| 必要なこと | 使用するもの |
|---|---|
| ソースからバイトを読み取る | impl Read(File、Cursor、stdin) |
| バッファー付きで読み取る(行、指定位置まで) | impl BufRead(BufReader でラップ) |
| 出力先にバイトを書き込む | impl Write(File、stdout、Vec) |
| ランダムアクセス | impl Seek(File) |
| 非同期 I/O | tokio::io::AsyncRead/AsyncWrite(rust-concurrency) |
use std::io::{BufRead, BufReader, Read, Write};
use std::fs::File;
let f = File::open("log.txt")?; // impl Read
let reader = BufReader::new(f); // wrap for BufRead
for line in reader.lines() { // BufRead::lines
println!("{}", line?);
}
Cursor<Vec<u8>>、エラー処理(io::Result)、同期処理と非同期処理の変換については、references/io-streams.md を参照してください。
パート 7:イテレーター
選び方
| 必要なこと | 使用するもの |
|---|---|
| 要素を借用する | .iter() → Iterator<Item = &T> |
| 可変借用する | .iter_mut() → Iterator<Item = &mut T> |
| 消費する | .into_iter() → Iterator<Item = T> |
| インデックス付きのペア | .iter().enumerate() |
| フィルターする | .filter(|x| *x > 0) |
| 変換する | .map(|x| x * 2) |
| 平坦化する | .flat_map(|x| x.iter()) |
| Vec に収集する | .collect::<Vec<_>>() |
| HashMap に収集する | .collect::<HashMap<_, _>>()((K, V) タプルから) |
| 最初に一致するもの | .find(|x| *x == 5) |
| いずれか/すべて | .any(|x| *x > 0)、.all(|x| *x > 0) |
| グループ化/合計 | .sum::<i32>()、.product()、.fold(0, |a, b| a + b) |
// Borrowed iteration is the default
let v = vec![1, 2, 3];
for x in &v { /* x: &i32 */ } // .iter()
for x in &mut v { /* x: &mut i32 */ }
for x in v { /* x: i32, v consumed */ }
カスタムイテレーター(Iterator の実装)、遅延評価、ゼロコスト抽象化については、references/iterators.md を参照してください。
パート 8:標準ライブラリの並行処理
標準ライブラリはスレッド、チャネル、同期プリミティブを提供します。非同期処理については、rust-concurrency を参照してください。
スレッド
use std::thread;
use std::time::Duration;
let handle = thread::spawn(|| {
thread::sleep(Duration::from_millis(500));
"result"
});
let r = handle.join().unwrap(); // wait, get result
スコープ付きスレッド(Rust 1.63+)— 'static なしで借用
let mut data = vec![1, 2, 3];
thread::scope(|s| {
s.spawn(|| { data[0] += 1; });
s.spawn(|| { data[1] += 1; });
}); // all threads joined here; data borrow ends
mpsc チャネル
use std::sync::mpsc;
use std::thread;
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send(42).unwrap();
});
println!("{}", rx.recv().unwrap());
同期プリミティブ
| プリミティブ | 用途 |
|---|---|
Mutex<T> | 排他ロック、同期的な内部可変性 |
RwLock<T> | 多数の読み取り、少数の書き込み |
Arc<T> | アトミックな参照カウント |
Barrier | 複数スレッドを特定の地点で同期する |
Once | 1 回限りの初期化 |
Condvar | 待機/通知 |
Atomic*(AtomicUsize、AtomicBool など) | ロックフリーのカウンター、フラグ |
Arc<Mutex<T>> のパターン、poison の回復、Tokio への移行タイミングについては、references/std-concurrency.md を参照してください。
パート 9:時間、パス、プロセス
時間
use std::time::{Duration, Instant, SystemTime};
let start = Instant::now();
expensive_op();
println!("took {:?}", start.elapsed()); // Duration
let five_secs = Duration::from_secs(5);
let mixed = Duration::new(5, 500_000_000); // 5.5s
let now = SystemTime::now();
let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH)?;
Duration— 時間の長さ(特定の時点ではありません)Instant— 経過時間の測定に使う単調な時点SystemTime— タイムスタンプ用の実時間(逆行することがあります!)
パス
use std::path::{Path, PathBuf};
let p = Path::new("/usr/bin/foo");
let stem = p.file_stem(); // "foo"
let ext = p.extension(); // "foo" → None; "foo.txt" → "txt"
let joined = PathBuf::from("/usr").join("bin").join("foo");
let parent = p.parent(); // "/usr/bin"
ファイルシステムのパスには、必ず Path/PathBuf を使用してください。String は使用しないでください。クロスプラットフォームで安全です。
プロセス
use std::process::Command;
let output = Command::new("ls")
.arg("-l")
.arg("/")
.output()?; // waits, returns Output
println!("{}", String::from_utf8_lossy(&output.stdout));
// Stream stdin/stdout
use std::process::Stdio;
let mut child = Command::new("cat")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
Command の終了コード、シグナル処理、fs モジュール(read、write、create_dir、メタデータ)については、references/process-and-fs.md を参照してください。
ワークフロー
- 必要なものを特定する — コレクション、ポインター、文字列、I/O、イテレーター、システムインターフェースのどれですか?
- 判断ツリーを適用する — 上記の該当するパートから選択します
- MSRV を確認する — 一部の API(
OnceLock1.70、LazyLock1.80、スコープ付きスレッド 1.63)には、最近の stable が必要です - コンビネーターで組み合わせる — 明示的な
matchよりも、Option/Resultのチェーンを優先します - 検証する —
cargo check、cargo test、cargo clippy - 引き継ぐ — 非同期ランタイム →
rust-concurrency、unsafe →rust-unsafe-ffi、アプリケーション関連の課題 → ドメインスキル
判断の早見表
| 質問 | 回答 |
|---|---|
| デフォルトのコレクションは? | Vec<T> |
| キーと値の検索が必要ですか? | HashMap(順序なし)または BTreeMap(ソート済み) |
| 所有権を共有しますか? | Rc(単一スレッド)または Arc(マルチスレッド) |
| 可変の共有状態が必要ですか? | RefCell(単一スレッド)または Mutex/RwLock(マルチスレッド) |
| 文字列パラメーターは? | 常に &str |
| ファイルパスは? | Path/PathBuf |
| 遅延初期化するグローバル変数は? | OnceLock(1.70 以降)または LazyLock(1.80 以降) |
| 借用して反復しますか? | .iter() |
| 両端キューは? | VecDeque |
| 優先度付きキューは? | BinaryHeap |
リソース
- コレクションの詳細
- スマートポインター
- 文字列型
- Option/Result コンビネーター
- I/O ストリーム
- イテレーター
- 標準ライブラリの並行処理
- プロセスとファイルシステム
- 内部可変性
- 標準ライブラリのモジュール一覧
examples/golden-stdlib/:コレクション、ポインター、チャネル、イテレーターを使用するクレート