2017-05-01から1ヶ月間の記事一覧

Rustのスレッドローカル変数について

Rustには2種類のスレッドローカル変数がある。 #[thread_local] 属性 #[thread_local] 属性は、指定した static アイテムをスレッドローカルにするようにLLVMに伝える。これによりC言語のスレッドローカル変数と同様に、ELFリンカ側の処理によりスレッドロー…

Rustにおけるキーワードの役割一覧

概要: Rustにおけるキーワードの役割をできる限り列挙する。キーワードではないものについても一部取り上げる。 強キーワード部門 キーワード 役割 as 修飾パス <T as Tr>::foo useとextern crateにおける別名 use foo as bar; 型の変換 x as usize box box式 box 1 b</t>…

Rustにおける記号の役割一覧

概要: Rustにおける記号の役割をできる限り列挙する。 ASCII制御文字部門 文字 役割 HT (水平タブ) 空白 LF (ラインフィード) 空白文字列中の改行シバン #! や行コメント // の終わり VT (垂直タブ) 空白 CR (キャリッジリターン) 空白CRLFでLFと等価に振る…

FnBoxについて

Rustの FnBox について、動機・仕組み・問題点を説明する。 FnBox の動機 以前の記事では、「「クロージャを boxせずに 返したい」という欲求は人類の四大欲求のひとつと言われている。 」と書いたが、出所の異なるクロージャを同じ型で扱う必要がある場合は…

Rustで引数型と戻り値型がSizedでなくてもよい条件

過去の記事でSizedについて説明したが、関数の引数と戻り値についてはやや直感に反する条件が適用されているので説明する。 戻り値型: 関数やメソッドが本体をもつ場合に検査される。本体を持たない場合は Sized でなくてもよい。 引数型: それ自体は検査さ…

RustのUnsafeCellとFreeze

概要: UnsafeCell の存在目的について説明する。 UnsafeCell とは UnsafeCell とは、その名前の通り、内部可変性(interior mutability)を実現するためのunsafeはプリミティブである。 UnsafeCell の代表的な用途は内部可変性を実現するための安全なラッパー…

Rustの身代わりパターン

概要: &mut 参照に対して所有権が必要な操作をするときは特定のパターンが用いられる。これを身代わりパターンとでも呼ぶことにする。 例: 単方向リンクリスト またしても単方向リンクリストを考える。 struct List<T> { root: Option<Box<Node<T>>>, } struct Node<T> { value</t></box<node<t></t>…

Rustコンパイラのデバッグ出力を見る

Rustコンパイラの細かい挙動を追うには、コンパイラ内に設置してある debug!(..) の出力を追う手がある。 デバッグ出力を有効化してコンパイラをビルドする まず手元のRustコンパイラのソースから、デバッグ出力を有効化したコンパイラを作成する必要がある…

Rustの基本型のメソッドはどこで定義されているか

概要: Rustの基本型そのものはコンパイラで特別に定義されている。では型に関連づけられたメソッドはどこにあるのか。 固有メソッドのありか 固有メソッドは core の各所で定義されている。例えば i32 の固有実装は core::numに定義されている。 #[lang = "i…

RustマクロでFizz Buzz

RustのマクロでFizz Buzzを書いてみた。 gist.github.com このFizz Buzzは、ループと倍数判定をマクロで処理している。10進数として表示する部分はマクロではなくRust本体に任せていりう。 動作の説明 Rustの macro_rules! でメタプログラミングを行う場合、…

Typed Arenaとdropck

概要: Typed Arenaはdropckの目的を説明するよい例になっている。 Typed ArenaとDrop 以前 Typed Arenaの紹介記事 を書いたが、このソースコードに以下のように Drop の実装を足してみる。 extern crate typed_arena; use std::cell::RefCell; use typed_are…

RustのNULLポインタ最適化

概要: RustのNULLポインタ最適化について説明する。 NULLポインタ最適化とは 以下のようにポインタ型のOptionが、元のポインタと同じサイズになる最適化である。NULLをNoneに割り当てている。 fn main() { println!("{}", std::mem::size_of::<Box<u32>>()); // 8 pri</box<u32>…

末尾再帰をループにできないRustプログラムの例

概要: 生存期間の関係で、ループでは書けないが末尾再帰では書けるアルゴリズムの例を挙げる。 単方向リンクリスト 次のような単純なリンクリストを考える。 struct List<T> { root: Option<Box<Node<T>>>, } struct Node<T> { value: T, next: Option<Box<Node<T>>>, } backの実装 単方向</box<node<t></t></box<node<t></t>…

Rustのshebang comment

shebangはRustではコメントとみなされる。 #!/bin/cat fn main() { println!("Hello, world!"); } shebangとみなされる条件は、 ファイル(字句解析の処理単位)の先頭である。 #! で始まっている。 #![ で始まっていない。 である。LF \n またはファイルの末…

君のRustは20倍遅い

Rustはデフォルトでは本来の力を発揮しない。試しに手頃なベンチマークを3個くらい試したらだいたい20~100倍程度遅かった。 「Rustで ○○ を高速にする方法」が知りたい人は、まず、Rustコンパイラが本来の力を発揮しているか確認したほうがよい。 Cargoの場…