rust

パターンマッチ ".." と "_"の違い

元ネタ Difference between ".." and "_" in match patterns. : rust _ 一つの値のみにマッチする .. 複数の値にマッチする let v = (1, 2, 3); match v { (1, 2, _) => println!("1, 2, _"), (1, ..) => println!("1, .."), (..) => println!(".."), }

Option<T>

Option enum Option<T> { None, Some(T), } boolに変換 is_some(&self) is_none(&self) 値の取り出し T expect(self), msg: &str) -> T unwrap(self) -> T unwrap_or(self, default: T) -> T unwrap_or_else<F>(self, f: F) -> T where F: FnOnce() -> T Result<T, E> ok</t,></f></t>…

型と所有権

型と変数と値 型は、struct,enumを使って定義し、値は型から生成され、変数に格納する。 // 型Vを定義 struct V(i32); // 変数aに値V(0)を格納する let a = V(0); 所有権とは 値を保持することができる変数は必ず1つであるという制約のこと。 #[derive(Debu…

ポリモーフィズム with トレイトオブジェクト

ポリモーフィズム (Polymophism) ポリモーフィズム in Rust deepLによる翻訳 ポリモーフィズム 多くの人にとって、ポリモーフィズムは継承と同義語です。しかし、実際にはもっと一般的な概念であり、複数の型のデータを扱うことができるコードを指します。継…

トレイトオブジェクト

Trait objects 動的サイズ決定型 (DSTs) トレイトオブジェクトは、以下のポインタを持つワイドポインタ(動的サイズ決定型) 値へのポインタ 仮想メソッドテーブル トレイトオブジェクトの形 Box<dyn SomeTrait> &dyn SomeTrait トレイトオブジェクトの目的 動的ディスパッチ</dyn>…

impl trait引数とジェネリクス関数の違い

元ネタ rust - What are the differences between an impl trait argument and generic function parameter? - Stack Overflow 回答 impl trait引数は、トレイト境界に脱糖(desugar)される。(ゆえにトレイト境界の糖衣構文である) したがって以下は同じ。 t…

anyhowを使う

anyhow::Error https://docs.rs/anyhow/1.0.44/anyhow/struct.Error.html 動的エラー型を包み込んだエラー型。 Box<dyn std::error::Error>との違い 静的な型 もどり道(backtrace)を保証する narrow pointer Display representations Display 表し方 esprintln!("{}", err) undering</dyn>…

anyhowメモ

anyhowのメリット エラーに説明を追加できる anyhow::Result<T>は、エラーの伝播ルートをスタックトレースとして出力してくれる anyhowがない場合 Result<T, E> と std::error::Errorトレイトを使う。 fn count_words<R: Read>(input: &mut R) -> Result<u32, Box<dyn Error>> { let reader = BufRe</u32,></r:></t,></t>…

Borrow<Borrowed>とToOwnedトレイト

Borrow<Borrowed>トレイト - Borrowed型を借用できることを表す ToOwnedトレイト - Borrow<Borrowed>型を実装すると自動実装される use std::borrow::Borrow; #[derive(Debug)] struct ToolBox(Tool); #[derive(Debug)] struct Tool; impl Borrow<Tool> for ToolBox { fn borrow(&self)</tool></borrowed></borrowed>…

エラーハンドリング構成 in 2020

元ネタ nick.groenen.me メモ std::error::Errorトレイトが抱える問題 スタックトレースがとれない。 アプリケーションとライブラリとでエラーのあり方が異なる ライブラリにおけるエラー 意味のあるエラーを返す必要がある ライブラリ内で発生したエラーは…

参照型 `&T` `&mut T`

Primitive Type 参照 &T or &mut T 参照, 共有と可変 参照は、ある所有された値の借用を表す。 & ,&mut 演算子もしくは、ref, ref mutキーワードを使って参照を得ることが出来る。 ポインタ型(*const T, *mut T)と違って、null出ないことが保証されている。 …

ジェネリクス Generics

Generic(総称型) vs Concreate(具体型) Rustにおいて、"generic"は、一つ以上のgeneric type parameters<T>を持つものである。 それ以外は、concrete(non-generic)である。 例: 関数 fn foo<T>(arg: T) { .... } 引数の型Tがジェネリクス型パラメーターが指定され</t></t>…

bat

概要 github.com 出力の整形や構文ハイライトをしてくれるツール。 プロジェクト構成 src構成 ▾ src/ ▾ bin/bat/ ツールファイル一式 app.rs assets.rs clap_app.rs config.rs directories.rs input.rs main.rs lib.rs ソースファイル一式 main関数 fn main(…

heap領域で確保される型

users.rust-lang.org Rustは通常スタック領域に値を確保するが、一部の型はヒープ領域で内部の値を確保し、その参照を返す。 Containers: Box Rc Arc Collections types: Vec, VecDeque String HashMap, HashSet BTreeMap, BTreeSet Concurrency: thread::sp…

Box<T>型

doc.rust-lang.org Rustの全ての値は、デフォルトはstack領域で確保される。 値は、Box<T>を生成することによって、boxed(ヒープ上での確保)することが出来る。 box値は、T型の値をヒープ上に確保するためのスマートポインタである。 box値がスコープから消えた</t>…

アンチパターン Deref ポリモフィズム

github.com use std::ops::Deref; struct Foo; impl Foo { fn m(&self) { println!("hello, I'm Foo"); } } struct Bar { f: Foo, } impl Deref for Bar { type Target = Foo; fn deref(&self) -> &Foo { &self.f } } fn main() { let bar = Bar { f: Foo, }…

メソッドの返り値として参照を渡すとその変数の借用が発生する

use std::collections::HashMap; #[derive(Debug)] struct A { fields: Option<HashMap<i32, String>>, } impl A { fn get(&self, key: i32) -> Option<&String> { if let Some(ref fields) = self.fields { if let Some(value) = fields.get(&key) { //return Some(value.clone()</hashmap<i32,>…

演算子

Operators Rustのオペレーターは、std::opsで定義されている。 演算子のオーバーロードは、対応するtraitを実装する。 Add + infix operator 定義 pub trait Add<Rhs = Self> { type Output; pub fn add(self, rhs: Rhs) -> Self::Output; } Rhs: RustはtraitもGenericパ</rhs>…

マクロルール(macro_rule!)を使って型の定義

image-rsから macro_rules! define_colors { {$( $ident:ident, $channels: expr, $alphas: expr, $interpretation: expr, $color_type_u8: expr, $color_type_u16: expr, #[$doc:meta]; )*} => { $( // START Structure definitions #[$doc] #[derive(Parti…

トレイト境界 サイズ未決定型を受け取れるようにする

トレイト境界はデフォルトでSized付けされる。 (Sized付けされるので、コンパイル時にサイズが決まっている必要がある) NG trait A { fn receive_from_b<T: B>(&self, b: &T); } trait B { fn send_a<T: A>(&self, a: T) { a.receive_from_b(self); } } /* error[E0277</t:></t:>…

トレイトオブジェクトになれないトレイト

Using Trait Objects That Allow for Values of Different Types - The Rust Programming Language 以下のメソッドを含むトレイトは、トレイトオブジェクトになれない (オブジェクトセーフではないため) Selfを返す ジェネリクス型 Note: Swiftでも型として…

カスタムの型をHashMapのキーにする時のための Borrow<Borrowed> トレイト

Vec<u8> をフィールドに持つ型Nameがあるとする。 struct Name<Vec<u8>> このNameをHashMapのキーとする場合、毎回Vecから生成する必要がこのままでは発生する。 fn get(&self, key: &[u8]) -> &String { let name = Name(key.to_vec()); self.0.get(&name).unwrap() } </vec<u8></u8>…

参照として値を取りだす if let式

if-let式 if-let式はunwrapなので、 Tがコピーセマンティクスならば、コピーされるが、そうでない場合は、所有権が移動する。 所有権を移したくない場合は、refキーワードを付けて、参照にする。(値を借用する) // buf1 : case Cmd(Vec<u8>) if let Cmd(ref cmd)</u8>…

可変参照のライフタイムにおける所有権の移動と再借用

元ネタ yohhoy.hatenadiary.jp いずれのケースでもm2の型は&mut i32に相当するが、厳密には参照のライフタイム(lifetime)が異なる別の型である 可変参照の変数束縛 ライフタイムが同一かどうかで、所有権が移動するかどうかが決まる。 同一: 移動する 異なる…

ライフタイムとライフタイム付き可変参照

struct MutableDataWithLifeTime<'a> { // ライフタイム付き可変参照 val: &'a mut i32, } struct ShortLifeTime; impl ShortLifeTime { fn take_data<'a>(data: &'a mut MutableDataWithLifeTime<'a>) { *data.val *= 2; } } struct LongLifeTime; impl Lon…

自己参照構造体は作ることが出来ない

Qiitaからのメモ 【Rust】構造体に自身のフィールドの参照の配列を持たせる方法 - Qiita struct Bullet<'a>(&'a Texture); struct Enemy<'a> { bullet_texture: Texture, bullets: Vec<Bullet<'a>> } impl<'a> Enemy<'a> { fn new(bullet_texture: Texture) -> Self { E</bullet<'a>…

強参照Rc<T> と弱参照Weak<T>

std::rc::Rc<T> 概要 動的な参照を実現。&演算子による参照がコンパイル時にされるのに対して、Rc<T>は実行時に参照を確保する。 これによってライフタイムを除去することができる。 ライフタイムの除去 参照による共有 借用チェッカーを通すために、ライフタイム</t></t>…

std::rc::Rc<T> と std::cell::RefCell<T>

Rc::borrow_mut の問題 let file = File::open("text.txt")?; let mut bufreader = BufReader::new(&file); let shared_reader = Rc::new(bufreader); // NG let _ = *shared_reader.borrow_mut().read_line(&mut line)?; /* error[E0599]: no method named …

循環参照 - Rc<T>とRefCell<T>

循環参照はメモリーをリークする Rustのメモリ安全保障において、メモリーリークを発生させることはとてつもなく難しい。 Preventing memory leaks entirely is not one of Rust's guarantees in the same way that disallowing data race at compile time i…

スマートポインタ Rc<T> - 参照カウンタ

Rc<T>, the Reference Counted Smart Pointer 所有権は多くの場合において明白である。つまり「1変数は、1つの値の所有する 」。 しかしながら 一つの値が複数の所有者を持つ ケースが存在する。 例として、グラフ構造がある。 グラフは、複数の辺が同一のノ</t>…