rsdocsjp - Rust言語非公式日本語ドキュメント
rsdocsjpは、Rust標準ライブラリおよび関連仕様について、公式ドキュメントの単純な翻訳ではなく、各ライターの理解と解釈に基づいて日本語で解説する非公式プロジェクトです。
正確性には最大限配慮していますが、内容の完全性・公式性を保証するものではありません。 原典については必ず公式ドキュメントを参照してください。
方針
本サイトは常にRust言語の最新リファレンスを掲載し続けることを目標にしています。 また、Rust言語の入門として使えるよう、わかりやすさも重視しております。 基本的には公式ドキュメントを参考にしながら、編集者の独自の理解と解釈に基づいて解説を書きます。
本サイトを閲覧するにあたって
本サイトはよりわかりやすくするために、コードブロックではフルパスを書くようにしています。 ただし、以下の構造体・トレイトなどは除外されます。
std::marker::Copystd::marker::Copy(deriveマクロ)std::marker::Sendstd::marker::Sizedstd::marker::Syncstd::marker::Unpinstd::ops::Dropstd::ops::Fnstd::ops::FnMutstd::ops::FnOncestd::ops::AsyncFnstd::ops::AsyncFnMutstd::ops::AsyncFnOncestd::mem::dropstd::mem::align_ofstd::mem::align_of_valstd::mem::size_ofstd::mem::size_of_valstd::clone::Clonestd::clone::Clone(deriveマクロ)std::cmp::Eqstd::cmp::Eq(deriveマクロ)std::cmp::Ordstd::cmp::Ord(deriveマクロ)std::cmp::PartialEqstd::cmp::PartialEq(deriveマクロ)std::cmp::PartialOrdstd::cmp::PartialOrd(deriveマクロ)std::convert::AsMutstd::convert::AsRefstd::convert::Fromstd::convert::Intostd::convert::TryFromstd::convert::TryIntostd::default::Defaultstd::default::Default(deriveマクロ)std::iter::DoubleEndedIteratorstd::iter::ExactSizeIteratorstd::iter::Extendstd::iter::IntoIterstd::iter::Iteratorstd::iter::FromIteratorstd::option::Optionstd::option::Option::Nonestd::option::Option::Somestd::result::Resultstd::result::Result::Errstd::result::Result::Okstd::fmt::macros::Debug(deriveマクロ)std::hash::macros::Hash(deriveマクロ)std::assertstd::cfgstd::columnstd::compile_errorstd::concatstd::envstd::filestd::format_argsstd::includestd::include_bytesstd::include_strstd::linestd::log_syntax(nightlyのみ)std::module_pathstd::option_envstd::stringifystd::trace_macros(nightlyのみ)std::concat_bytes(nightlyのみ)std::future::Futurestd::future::IntoFuture
フルを書かないパスはstd::prelude::rust_2024に基づいています。
ライセンス
Rustの慣習に従い、明記されてない限りはMIT OR Apache License 2.0で管理されています。
モジュール一覧
現在掲載されているモジュールの一覧です。
モジュール std::vec
バージョン
Rust 1.0.0 ~
概要
型消去と型リフレクションに関する機能を提供する。
構造体
| 名前 | 説明 |
|---|---|
TypeId | グローバルに一意な型の識別子を提供する |
トレイト
| 名前 | 説明 |
|---|---|
Any | 動的型付けを模倣する |
関数
| 名前 | 説明 |
|---|---|
type_name | ジェネリクスに渡された型の名前を取得する |
type_name_of_val | 引数に渡された値の方の名前を取得する |
モジュール std::boxed
バージョン
Rust 1.0.0 ~
概要
Box<T>はヒープアロケーションのための型である。
Box<T>(単に ‘Box’ と呼ばれることもある)はRustにおいて一番単純なヒープアロケーションである。Boxはこのアロケーションの所有権を有し、スコープから外れる時に中身を破棄する。加えて、ヒープの割り当てがisize::MAXバイトを超えないことも保証する。
例
Boxを作成してスタックの値をヒープへ移動する:
#![allow(unused)]
fn main() {
let val: u8 = 5;
let boxed: Box<u8> = Box::new(val);
}
#![allow(unused)]
fn main() {
let boxed: Box<u8> = Box::new(5);
let val: u8 = *boxed;
}
再帰データ構造の作成:
#![allow(unused)]
fn main() {
#[derive(Debug)]
enum List<T> {
Cons(T, Box<List<T>>),
Nil,
}
let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
println!("{list:?}");
}
上記のプログラムの結果はCons(1, Cons(2, Nil))となる。
再帰データ構造にはBox化が必要である。例えばConsを下記のように定義した場合コンパイルエラーとなる:
#![allow(unused)]
fn main() {
Cons(T, List<T>),
}
なぜならListのサイズはリスト内にどれだけのリストがあるかにより、このままではConsに対するスタックの割り当て量を把握できないためである。サイズが決まっているBox<T>を用いることで、Consに必要なスタックサイズが把握できるようになる。
メモリーレイアウト
サイズが0でない値では、Boxはメモリー割り当てのためGlobalアロケーターを使用する。アロケーターの引数として使用されるLayoutが適切な型であり、生ポインターがその型の有効な値を示す場合に、BoxとGlobalアロケーターに割り当てられた生ポインターは相互に変換できる。より詳しく言うと、Layout::for_value(&*value)とともに使用されるGlobalアロケーターに割り当てられたvalue: *mut TはBox::<T>::from_raw(value)を使用してBoxへと変換できる。逆にBox::<T>::into_rawから得られたvalue: *mut TはLayout::for_value(&*value)とGlobalアロケーターによって解放できる。
サイズが0の値では、Boxは非ヌルでありアライメントされている必要がある。Box::newが使用できない場合にZST(ゼロサイズ型)のBoxを作成する推奨方法はptr::NonNull::danglingを使用することである。
これらの基本的なLayoutの要件に加えて、Box<T>は有効な値Tを示さなければならない。
T: Sizedである限りBox<T>は単一のポインターであることを保証するとともにCのポインター(CのT*型)とのABI互換性を持つ。これはRustでCから呼び出す関数を作成する際にBox<T>で定義したものがCではT*になるという意味である。例としてFooの作成と破棄を行う関数を宣言するCのヘッダーを示す:
/* C ヘッダー */
/* 呼び出し元への所有権の返却 */
struct Foo* foo_new(void);
/* 呼び出し元から所有権を取得; ヌルの場合何もしない */
void foo_delete(struct Foo*);
この2つの関数はRustで下記のように実装できる。ここではstruct Foo*型に変換されたBox<Foo>は所有権の制約を補足する。Box<Foo>が非ヌルであるため、引数がヌルになる可能性のあるfoo_deleteの引数はRustではOption<Box<Foo>>になることに注意しなければならない。
#![allow(unused)]
fn main() {
#[repr(C)]
pub struct Foo;
#[unsafe(no_mangle)]
pub extern "C" fn foo_new() -> Box<Foo> {
Box::new(Foo)
}
#[unsafe(no_mangle)]
pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}
}
Box<T>はCのABIにおいてCのポインターと同じ表現を持つが、これはいつでもT*をBox<T>へ変換したり変換したものが上手く機能するという意味ではない。Box<T>の値は常にメモリーアライメントされた非ヌルのポインターであり、デストラクターはグローバルアロケーターでの値の開放を試みる。一般的なベストプラクティスはBox<T>をグローバルアロケーターから生成されるポインターとしてのみ使用することである。
重要 少なくとも現時点ではRustから呼び出されるCで定義された関数の型にBox<T>を使用すべきではない。この場合ではCの型に可能な限り近い型を直接使用すべきである。rust-lang/unsafe-code-guidelines#198に記載されているように、Box<T>をCの定義で単にT*のように使用すると未定義動作につながることがある。
アンセーフなコードへに対する考慮
注意:このセクションは規範的でなく変更の可能性を含んでおり、将来的に緩和される可能性がある。これは現在コンパイラーに実装されていルールの要約である。
Box<T>へのエイリアスのルールは&mut Tと同じものである。Box<T>は保有する中身の一意性を持つ。&mut Tのような移動や借用によって変更されたBoxから取得した生ポインターの使用は許可されていない。rust-lang/unsafe-code-guidelines#326にアンセーフなコードでのBoxの使用に関する更なる説明がある。
エディション
このドキュメントにある通り、Rust 2021までのエディションの配列にはIntoIteratorの実装の特別なケースが存在する。後にBox化したスライスにも同様の回避策を追加する必要が判明したため、残念ながら回避策の適用は2024エディションになった。
具体的には、IntoIteratorはすべてのエディションのBox<[T]>に実装されているが、Box化したスライスに対するinto_iter()の適用は2024以前のエディションの実装に従う。
#![allow(unused)]
fn main() {
// Rust 2015, 2018, 2021:
let boxed_slice: Box<[i32]> = vec![0; 3].into_boxed_slice();
// スライスから各々の値を参照した iterator を作成する。
for item in boxed_slice.into_iter().enumerate() {
let (i, x): (usize, &i32) = item;
println!("boxed_slice[{i}] = {x}");
}
//`boxed_slice_into_iter`は将来の互換性のため、リンターに下記への変更を提案される:
for item in boxed_slice.iter().enumerate() {
let (i, x): (usize, &i32) = item;
println!("boxed_slice[{i}] = {x}");
}
// Box 化したスライスから値の iterator を作成する場合、`IntoIterator::into_iter`を使用して明示的に宣言できる。
for item in IntoIterator::into_iter(boxed_slice).enumerate() {
let (i, x): (usize, i32) = item;
println!("boxed_slice[{i}] = {x}");
}
}
配列の実装と同様に、このオーバーライドは将来修正される可能性があり、後方互換性を維持したい場合はこれらのエディション間の違いに頼った挙動を避けるべきである。
構造体
モジュール std::vec
バージョン
Rust 1.0.0 ~
概要
可変長配列であるVecとそのイテレーター群を提供する。
構造体
| 名前 | 説明 |
|---|---|
Drain | ベクター内の指定された区間を削除し、取り除かれた要素を与えるイテレータ |
IntoIter | ベクター内の指定された区間の所有権を奪うイテレータ |
Splite | ベクター内の指定された区間を与えられたイテレーターと入れ替え、元の要素を返すイテレータ |
構造体 std::vec::Drain
pub struct Drain<'a, T, A = std::alloc::Global>
where
T: 'a,
A: std::alloc::Allocator + 'a
{ /* private fields */ }
バージョン
Rust 1.6.0 ~
解説
Note
ジェネリクス
Aを明示的に使えるのはnightlyのみ
ベクター内の指定された区間を削除し、取り除かれた要素を与えるイテレータ。
Vecのdrainメソッドによって作成される。
例
#![allow(unused)]
fn main() {
let mut v = vec![0, 1, 2, 3];
let u = v.drain(1..).collect::<Vec<_>>();
// 前から2番目以降の要素が削除されている
assert_eq!(v, &[0]);
// 削除された要素が返されている
assert_eq!(u, &[1, 2, 3]);
}
実装
impl<T, A> Drain<'_, T, A>
where
A: std::aloc::Allocator
{ /* private fields */ }
impl<'a, T, A> Drain<'a, T, A>
where
A: std::alloc::Allocator
{
pub fn as_slice(&self) -> &[T];
// nightly-only
pub fn allocator(&self) -> &A;
// nightly-only
pub fn keep_rest(self);
}
as_slice
Rust 1.46.0 ~
#![allow(unused)]
fn main() {
pub fn as_slice(&self) -> &[T]
}
まだ削除されていない要素をスライスで返す関数。
#![allow(unused)]
fn main() {
let mut v = vec![0, 1, 2, 3];
let mut drain = v.drain(..);
// まだ何も消費していない
assert_eq!(drain.as_slice(), &[0, 1, 2, 3]);
// 1個前に進める(1個消費する)
let _ = drain.next().unwrap();
// 1番目の要素が削除される
assert_eq!(drain.as_slice(), &[1, 2, 3]);
}
allocator
Note
nightlyでのみ使用可能
#![allow(unused)]
fn main() {
pub fn allocator(&self) -> &A
}
内部で使用しているアロケーターを返す関数。
#![allow(unused)]
#![feature(allocator_api)]
fn main() {
use std::any::{Any, TypeId};
let v = vec![0, 1, 2, 3];
assert_eq!(
// allocatorは参照を返すためcloneする
v.allocator().clone().type_id(),
// Vecのアロケーターはデフォルトでstd::alloc::Global
TypeId::of::<std::alloc::Global>()
);
}
keep_rest
Note
nightlyでのみ使用可能
#![allow(unused)]
fn main() {
pub fn keep_rest(self)
}
一度も消費していない要素をもとのベクターに返還する関数。
#![allow(unused)]
#![feature(drain_keep_rest)]
fn main() {
let mut v = vec![0, 1, 2, 3];
let mut drain = v.drain(..);
// ひとつ前に進める(一つ消費する)
drain.next().unwrap();
// vに消費していない要素を返還する
drain.keep_rest();
assert_eq!(v, [1, 2, 3]);
}
トレイト実装
AsRef
impl<'a, T, A> AsRef<[T]> for Drain<'a, T, A>
where
A: std::alloc::Allocator
{ /* trait methods */ }
std::fmt::Debug
impl<T, A> std::fmt::Debug for Drain<'_, T, A>
where
T: std::fmt::Debug,
A: std::alloc::Allocator,
{ /* trait methods */ }
DoubleEndedIterator
impl<T, A> DoubleEndedIterator for Drain<'_, T, A>
where
A: std::alloc::Allocator
{ /* trait methods */ }
Drop
impl<T, A> Drop for Drain<'_, T, A>
where
A: std::alloc::Allocator
{ /* trait methods */ }
ExactSizeIterator
impl<T, A> ExactSizeIterator for Drain<'_, T, A>
where
A: std::alloc::Allocator
{ /* trait methods */ }
Interator
impl<T, A> Iterator for Drain<'_, T, A>
where
A: std::alloc::Allocator
{ /* trait methods */ }
std::iter::FusedIterator
impl<T, A> std::iter::FusedIterator for Drain<'_, T, A>
where
A: std::alloc::Allocator
{ /* trait methods */ }
Send
impl<T, A> Send for Drain<'_, T, A>
where
T: Send,
A: Send + std::alloc::Allocator
{ /* trait methods */ }
Sync
impl<T, A> Sync for Drain<'_, T, A>
where
T: Sync,
A: Sync + std::alloc::Allocator
{ /* trait methods */ }
std::iter::TrustedLen
impl<T, A> std::iter::TrustedLen for Drain<'_, T, A>
where
A: std::alloc::Allocator
{ /* trait methods */ }
std::marker::Freeze
impl<'a, T, A> std::marker::Freeze for Drain<'a, T, A> {
/* trait methods */
}
std::panic::RefUnwindSafe
impl<'a, T, A> std::panic::RefUnwindSafe for Drain<'a, T, A>
where
T: std::panic::RefUnwindSafe,
A: std::panic::RefUnwindSafe
{ /* trait methods */ }
Unpin
impl<'a, T, A> Unpin for Drain<'a, T, A> {
/* trait methods */
}
std::panic::UnwindSafe
impl<'a, T, A> std::panic::UnwindSafe for Drain<'a, T, A>
where
T: std::panic::RefUnwindSafe,
A: std::panic::RefUnwindSafe
{ /* trait methods */ }
貢献について
rsdocsjpに貢献したい方はまず、GitHubのCONTRIBUTING.mdを読みましょう。
貢献者一覧はこちらです。