ジェネリクスとトレイトオブジェクトの破壊的変更への対処

動機 ジェネリクスとトレイトオブジェクトの抱える問題 壮大たる破壊的変更につながる。 例 Fileインスタンスを持つStreamをジェネリクスに変更する struct Stream { reader: std::fs::File, } impl Stream { fn new(reader: std::fs::File) { Stream { read…

関数パラメーターにおける参照外し

関数パラメーターにおいても参照外しを行うことができる 例1 クロージャー map関数 let result = [1,2,3,4,5].iter().map(|&&x| x % 2 == 0).collect(); &&x : 参照参照外しをおこなっている 例2 関数の定義 参照外ししない場合 fn print_type_name<T>(_val: T)</t>…

Cargoプロジェクト Examplesの追加

Cargoで作ったライブラリプロジェクトにExamplesを追加することができる。 xion.io // examples/hello.rs fn main() { println!("Hello from an example!"); } $ cargo run --example hello $ cargo run --example hello2 -- Alice

トレイトオブジェクトの保持とライフタイム

トレイトオブジェクトとライフタイム トレイトオブジェクトを保持する場合は、ライフタイムが必要となる時がある。 ジェネリクス型パラメーター 参照型 トレイトオブジェクト x ジェンリクス型パラメーター struct Zoo { animals: Vec<Box<dyn Animal>>, // trait Animal { .</box<dyn>…

トレイト - 共通の振る舞いを定義する

https://doc.rust-lang.org/book/ch10-02-traits.html トレイト: 共通の振る舞いの定義 概要 トレイトを使って共通の振る舞いを定義 トレイトのデフォルト実装 トレイトをパラメーターに指定できる impl Trait トレイト境界 impl Traitのシンタックスシュガ…

トレイトの選択 完全限定構文 (Fully Qualified Syntax)

Fully Qualified Syntax Fully Qualified Syntax for Disambiguation: Calling Methods with the Same Name https://doc.rust-lang.org/book/ch19-03-advanced-traits.html fully qualified syntax (完全限定構文?) <Type as Trait>::function(receiver_if_method, next_arg</type>…

Iterator / IntoIterator / FromIterator

trait Iterator pub trait Iterator { type Item; fn next(&mut self) -> Option<Self::Item>; 実装している主要な型 std::slice::Iter<'a, T> Iterator派生型 Map Filter String.bytes Note: Vec<T>や配列[T]はIteratorではない。 これらがfor文で使えるのは、暗黙的にInto</t></self::item>…

クロージャー

概要 Rustのラムダ式はクロージャーと呼ぶ 関数ポインタ(fn)は、外部環境変数を含めることができない 関数ポインタもクロージャートレイトを実装している クロージャーの種類 (キャプチャー方法が異なる) FnOnce<Args>: selfメソッド, キャプチャー変数を消費する</args>…

スマートポインタの役割

Rustは関数ローカルの変数を参照として返すことができない impl Reader { fn new(path: impl AsRef<std::path::Path>) -> Reader { let file = std::fs::File::open(path).unwrap(); Reader { file: file, } } fn read_bytes(&mut self, len: usize) -> &[u8] { let mut bytes</std::path::path>…

トレイト まとめ

Self 将来実装される型を表す。 pub trait FromStr { type Err; fn from_str(s: &str) -> Result<Self, Self::Err>; impl FromStr for Haskellで言うところの型変数 a class Eq a where Eq: 型クラス a: 型変数, 具体型である必要がある。(型コンストラクタはNG) 関連型 type </self,>…

Borrow<Borrowed: ?Sized>トレイトとToOwnedトレイト

Stringの借用は、&strとして、&strの所有は、Stringとして表すことが出来る。 Rustでは、こういった関係をBorrow<Borrowed: ?Sized>とToOwnedトレイトを使って表すことが出来る。 Note: 参照 - ある所有された値への借用を表す型。コピーセマンティックである。 trait Borrow<Borrowed: ?Sized> </borrowed:></borrowed:>…

PDFファイル解析にあたって

PDFファイル解析にあたって RustでPDF解析ツールを作成するにあたって、PDFの仕様をまとめる。 (作成プログラムはPDF.jsを参考に実装予定) PDFとは PDF32000_2008 1. Introduction より抜粋して意訳 PDFは、ISO 32000によって規定されている電子ドキュメント…

PDFとPostScriptの違い

https://www.adobe.com/jp/print/postscript/pdfs/PLRM.pdf Introduction THE POSTSCRIPT® LANGUAGE is a simple interpretive programming language with powerful graphics capabilities. Its primary application is to describe the appearance of text,…

forループ文

TL;DR for文で回すには、以下のトレイトのどれかを実装する必要がある。 Iterator IntoIterator 配列はforループで回せない 配列は、どちらも実装していないため、forループ文で直接回せない。 let arr = [1,2,3,4,5]; // NG for i in arr { dbg!(i); } /* e…

配列型

配列型 サイズ固定配列。[T; N]で表す。 生成には2つの構文がある。 [x, y, z] [x; N]: 値xはCopy実装型でなければならない 配列は以下のトレイトを実装する。(ただしTも同様に実装されている必要がある) Copy Clone Debug IntoIterator: &[T; N]もしくは&m…

Iterator::findクロージャーに&&を渡さなければならない理由

https://stackoverflow.com/questions/43828013/why-is-being-used-in-closure-arguments let a = [1, 2, 3]; assert_eq!(a.iter().find(|&&x| x == 2), Some(&2)); assert_eq!(a.iter().find(|&&x| x == 5), None); 回答 aは[i32;3]型 [i32;3]型はiterメソ…

refキーワード

ref キーワード 参照として値を受け取ることが出来る let ref num = 5; // &i32 パターンマッチ内でも使用することが出来る let mut triple = (1, 2, 3); match triple { (1, ref mut second, 3) => *second *= 2, _ => panic!(), } dbg!(triple); // (1, 4,…

match式による構造破壊マッチング

match式による構造破壊マッチング match式のパターンマッチ内において、値を構造破壊することが出来る。 Destructuring Tuples タプル値を構造破壊してパターンマッチ let triple = (0, -2, 3); match triple { (0, y, z) => plintln!("First is `0`, `y` is…

型の種類とプリミティブデータ型

型の種類 T: 通常型 &T: 参照型 - ある所有された値への借用を表す型 [T; N] : 配列型 [T] : スライス型 *const T : ポインタ型 (T, U, V) : タプル型 fn(T) -> V : 関数型 プリミティブデータ型 bool char 一つのユニコードスカラー値 (4バイト表現) let x …

型 作成と実装

型(Type)の作成と実装 Rustは型(Type)の作成と実装が分かれる。 (最近はトレイトも実はサイズを持たない型(Type)と言えるのではないかと思うようになった) 型の作成は、struct, enumを使い、実装は impl を使う。 型の作成 struct enum Struct struct Point…

参照型とポインタ型

参照型とポインタ型 参照型 &T / &mut T - ある所有された値への借用を表す型 ポインタ型 *const T / *mut T - nullを表すことができる ポインタ型を使うメリットとデメリット Rustではポインタ型は、値がnullの可能性がある。 したがって扱う場合は、unsafe…

Iterator::collect()

Iterator::collect() fn collect<B>(self) -> B where B: FromIterator<Self::Item>, IteratorをCollectionに変換する。 collect()で変換できるCollectionはFromIterator<Self::Item>トレイトが実装されている必要がある。 Trait std::iter::FromIterator pub trait FromIterator<A> { fn f</a></self::item></self::item></b>…

単精度浮動小数点数への変換

123 2進数に変換 0b1111011 単精度浮動小数点数形式に正規化 0b1.111011 x 2^(6) 単精度浮動小数点数データ構造に変換 符号部: 0 指数部: 6 + 127 = 134 仮引数部: 11101100000000000000000 Swiftによる確認 let f = 123 as Float print("符号: ", f.sign) p…

単精度浮動小数点数(IEEE754) の作り方

書いたこと 単精度浮動小数点数形式とデータ構造 10進数から単精度浮動小数点数データ構造への変換 精度と誤差 単精度浮動小数点数形式とデータ構造 2進数をそのままでは単精度浮動小数点数データ構造に変換することはできない。 一旦、単精度浮動小数点数…

関数ポインタとクロージャー

関数ポインタ fn do_twice(f: fn(i32) -> i32, arg: i32) -> { f(arg) + f(arg) } // add_one: fn(i32) -> i32 do_twice(add_one, 1); fn: 関数ポインタを表す 関数の引数にわたすことが出来る 3つのクロージャートレイト(Fn, FnMut, FnOnece)を実装している…

Cargo 開発コマンドチートシート

プロジェクトの生成 cargo new プロジェクト名 ./cargo/binディレクトリへのインストール cargo install -path . --path .: カレントディレクトリ配下のCargoプロジェクトをインストールする tomlの編集 cargo-editをインストールする必要がある。 外部クレ…

Result型 のアンラップとエラーの伝搬

Result<T, E>型の特徴 Rustは例外処理が存在しない代わりに、Result型でそれを実現する。 値のアンラップ エラーの伝搬 値のアンラップ unwrap: Err時、panic!を引き起こす unwrap_or: Err時、デフォルト値を返す unwrap_or_else: Err時、デフォルト値を生成する関</t,>…

Result map処理

Resultに用意されているmap処理 map: Okの型を変換する map_err: Errの型を変換する map_or: 値をアンラップする。デフォルト値を渡せる map_or_else: 値をアンラップする。デフォルト値の評価を遅延評価する map(成功時のmap処理) Result<T, E> から Result<U, E>に変換</u,></t,>…

標準入力から文字列を受け取る

<C-c>が入力されるまで受け付ける fn main() { // 標準入力へのハンドルを生成 (各ハンドルはバッファーを共有される) let stdin = std::io::stdin(); // lockすることでバッファーを専有する let stdin = stdin.lock(); // <C-c>が入力されるまで受け付ける for line </c-c></c-c>…

::<T> turbofishの役割

ジェネリクスのパラメーターを指定する 例1 std::any::type_name<T>() -> &'static str fn type_of_val<T>(_val: T) ->&'static str { std::any::type_name::<T>() } 例2 std::iter::Iterator::collect<B>(self) -> B let tokens = "xyz 1 1.0 *".split_whitespace().col</b></t></t></t>…