rust

Result型をunwrapする際に、型パラメーターEがDebugを実装しているか指定する必要があるとき

fn read<T>() -> T where T: FromStr { let mut buffer = String::new(); let mut stdin = stdin().lock(); let _ = stdin.read_line(&mut buffer); T::from_str(&buffer.trim()).unwrap() // エラー <T as FromStr>::Err doesn't implement `Debug` } 原因は、 Result<T, E>型は、u</t,></t></t>…

Deref型

Deref型 代表的なDeref型 参照型 &T スマートポインタ String, Box<T>, ... 3つのDeref型強制 参照(More on Deref coersion) If T implements Deref<Target = U>, and x is a value of type T, then: In immutable contexts, *x (where T is neither a reference nor a raw</target></t>…

*演算子(Dereference)とスマートポインター

*演算子(Dereference演算子)は 参照型につかうと、参照外しされる。 スマートポインター(Deref実装型)に使うと、Deref型強制される。 メモ pub trait Dref { type Target: ?Sized; fn deref(&self) -> &Self::Target; } 不可変参照外し演算子(*v)によって使…

参照型 &T

参照型 &T 値を所有していないことを表す型。 &演算子(Borrow演算子)によって生成する。 借用 Rustでは、&演算子によって参照型を生成することを「値を借用する」という。 let a = String::from("a"); // 変数aの値を借用する let b: &String = &a; 値のライ…

自動参照外し (Auto-dereferencing)

元ネタ https://sodocumentation.net/rust/topic/2574/auto-dereferencing The dot operator ドット演算子 .演算子によって、コンパイル時に必要なだけの*が挿入され、自動で参照外しが行われる。 Deref型強制の一種。 let mut name: String = "Hello World"…

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

元ネタ 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>…

所有権と借用

所有権 Ownership 所有権とは 所有権と値のライフスコープ 所有権の移動 コピーセマンティクス Copyトレイト実装型 基本型 (bool, i32, ...) 参照型 ムーブセマンティクス 所有権とは 値を保持できる変数は、必ず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)と違って、nul…

ジェネリクス 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…