yohhoyの日記

技術的メモをしていきたい日記

Rust

todo!とunimplemented!の違い

プログラミング言語Rustのtodo!マクロとunimplemented!マクロの違い。 todo!:作業途中のコード。あとで実装する。 unimplemented!:現行コードでは未実装(実装するとは言っていない) The difference between unimplemented! and todo! is that while todo…

オブジェクトのDrop順序

プログラミング言語Rustにおける、オブジェクトデストラクト(Drop)順序についてメモ。[本記事はRust 1.32/Stable準拠] 変数は、その変数宣言順序の逆順。 ただし同一パターン内の変数同士では、順序未規定(unspecifined)。 構造体(struct)、タプル、列挙型…

入れ子Optionの平坦化(flatten)

プログラミング言語RustにおいてOption<Option<T>>からOption<T>へ変換する方法。 // ナイーブな実装 fn flatten<T>(x: Option<Option<T>>) -> Option<T> match x { Some(x) => x, None => None, } } // and_thenコンビネータ fn flatten<T>(x: Option<Option<T>>) -> Option<T> { x.and_then(|x| x) } // </t></option<t></t></t></option<t></t></t></option<t>…

危険な型変換:&T→&mut T

プログラミング言語Rustにおける、&Tから&mut Tへの型変換*1と同オブジェクトに対する変更操作は、未定義動作(undefined behavior)とされている。これは単にRustコンパイラのBorrow Checkerを騙すだけでなく、該当プログラムの動作が不定となり深刻な障害要…

to be, or not to be?

Rust標準ライブラリのコメントより。整数型*1に対してBig Endianへの変換メソッドto_beが提供される。その他にもEndianness変換メソッドto_le, from_be, from_leが提供される。 pub fn to_be(self) -> Self { // or not to be? if cfg!(target_endian = "big…

From/Intoトレイトと反射律

Rust標準ライブラリが提供する std::convert::From トレイトは、任意の型に対して反射律(reflexive law)を満たす。Fromトレイトにより実装される std::convert::Into トレイトもまた反射律を満たす。[本記事はRust 1.12/Stable準拠] struct T; let v1: T =…

Option型とNull Pointer Optimization

Rust標準ライブラリが提供するヌル許容型 std::option::Option<T> の空間オーバーヘッドについてメモ。[本記事はRust 1.11/Stable準拠]まとめ: T型がポインタ的に振る舞う(有効値が非ゼロと保障できる)場合、ヌルポインタ最適化(null pointer optimization</t>…

forループとイテレータ

Rust言語のfor構文と IntoIteratorトレイト に関するメモ。[本記事はRust 1.11/Stable準拠] for x in expression { // ループ本体 } Rust公式ドキュメントによれば、forループでは下記コードと等価な処理が行われる。式 expression に対して IntoIterator:…

str型とToStringトレイト

Rust 1.9にてstr型のToStringトレイト特殊化(specialization)が実装され、to_stringメソッドによるstr型からString型への変換処理が効率化された。[本記事はRust 1.11/Stable準拠]Rust 1.8以前はトレイト実装特殊化は存在せず、to_stringメソッドはジェネ…

ミュータブル参照のムーブと再借用

Rust言語のミュータブル参照(&mut T)の振る舞いについてメモ。[本記事はRust 1.10/Stable準拠]ミュータブル参照m1から新しいミュータブル参照m2を変数束縛(variable binding)するとき、型の明示有無によって(a)ミュータブル参照の所有権が移動(ムーブ)す…

ラムダ式はFnOnce/FnMut/Fnトレイト実装の糖衣構文

プログラミング言語Rustのラムダ式(lambda expression)は、トレイトFnOnce / FnMut / Fn を実装(impl)したクロージャ(closure)を作り出す、一種の糖衣構文(syntax sugar)として機能する。 Closure implementation Rust's implementation of closures is a bi…

where節でしか記述できない型制約

Rust言語のジェネリック関数(generic function)では、トレイト(trait)を用いて型パラメータ(parameterized types)の制約(bounds)を表現できる。これには2種類の記述方式が存在するが、where節でのみ表現可能な型制約がある。下記のように、ジェネリック関数…

マクロ呼出しに使える括弧記号

Rust言語のマクロ呼出しには(), [], {}のいずれかを利用できる。[本記事はRust 1.0/Stable準拠] let v1 = vec!(1, 2, 3); let v2 = vec![1, 2, 3]; let v3 = vec!{1, 2, 3}; let v1 = vec!(0; 3); let v2 = vec![0; 3]; let v3 = vec!{0; 3}; println!("He…

ブロック式とセミコロン

Rust言語では{〜}によるブロック構造も式(block expression)として扱う。[本記事はRust 1.0/Stable準拠]ブロック式全体の評価結果は、次の型/値となる。 唯一の部分式、または最終セミコロン;の次に出現する部分式の型/値。 ブロック式内が;で終わってい…