Rustコトハジメ

プログラミング言語Rustに関する情報をお届けします。

言語仕様

impl T for Box<T>パターン

GitHub - akiradeveloper/ijk: A real editor for real programmers 現在、私はエディタを開発しています。その中で知った設計パターンについて紹介します。 問題の定義 解決編 STEP1: BoxをViewにしてみる STEP2: Vに?Sizedを足す STEP3: selfをderefしてあ…

Copyトレイトとその応用例

Copyトレイトとは Copyトレイトが満たすべき条件 Copyトレイトの応用例 Copyトレイトとは Copyトレイトは、その値をまるまるコピー出来ることを表すマーカートレイトである。Copyトレイトを実装するとデフォルトのムーブからコピーになる。 pub trait Copy :…

トレイトの型を見れば何をするのかがわかる

私が混乱したこと 所有権や参照のコントロールはトレイトの責務 トレイトの定義を見れば、それが何をしたいのかわかる 例外ケース 私が混乱したこと Rustを勉強し始めた当時、私を混乱させたのは、 impl XXX for [T] のような書き方でした。 [T]というのは直…

try!マクロはfromを使ってエラーをリターンする

この記事では、少しoutdatedな話題ではあるようなのですが、以下のドキュメントから、Rustを書くに当たって知るべきエラーハンドリングについて基礎を学んでみたいと思います。 https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/error-han…

クロージャのスーパートレイト実装はコンパイラが生成してる

www.rustforbeginners.com で、クロージャはコンパイラが生成しているということをお話しました。 しかし、積み残し課題として、自身のスーパートレイトがどうやって実装されているのかわからないという話をしました。 スーパートレイトというのは、3つのク…

IteratorのメソッドがFnMutをとるのはなぜでしょうね

Rustのイテレータは関数型プログラミングが出来るようになっていて、例としてmapやfoldのような関数があります。 fn map<B, F>(self, f: F) -> Map<Self, F> where Self: Sized, F: FnMut(Self::Item) -> B, fn fold<B, F>(mut self, init: B, mut f: F) -> B where Self: Sized, </b,></self,></b,>…

Rustにおけるスマートポインタとは

www.rustforbeginners.com で、Vecは3つのデータを持つ構造だと言った。そして、この時には所有権を持つ者ということで所有者という言葉を使った。 このように、内部に特殊なメタデータを持つポインタライクなものを、Rustではスマートポインタという。 Rust…

Arc<Mutex<T>>という形はデザインパターン

RustはGCのない言語なので、GCがあった時にふつうに書けていたコードが書けなくなります。その典型例はリスト・ツリー・グラフといった再帰的な構造です。 これに対してドキュメントや記事を読むと、以下のような型が出てきます。Haskellのモナドスタックの…

整数の参照が足し算出来る理由

このコードって驚きますか?C言語出身の人からすると、何を言ってるんだという感じになると思いますが、 fn main() { let a = 5; let b = 3; println!("{},{},{},{}", a+b, a+&b, &a+b, &a+&b) } 結果は、 8,8,8,8 となります。 この背景にあるのはマクロで…

Indexトレイトをしゃぶり尽くす

fn main() { let mut v = vec![1, 2, 3, 4, 5]; let a = &v[0]; v.push(6); } このプログラムをコンパイルすると、 error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable --> prog.rs:4:5 | 3 | let a = &v[0]; | - immuta…

Rustのクロージャはコンパイラによって生成されたクラスである

Rustにおける3つのクロージャ 共有借用と可変借用を混ぜた場合のクロージャを実験 考察 積み残し課題 Rustにおける3つのクロージャ Rustでは、クロージャはそれぞれ全く異なるクラスが生成され、それらがFnやFnMutといったトレイトを実装します。そして、Fn:…

ゼロコスト抽象化とは一体何なのか

「ゼロコスト抽象化」という言葉を最初に聞いた時、正直にいうと何のことだかわかりませんでした。これは別途記事にしようと思いますが、freeしなくていいのにGC不要と書いてあって何を言ってるのかさっぱりわからなかったのと同様に、抽象化のコストがゼロ…

なぜIntoからFromへの実装が定義されていないのか実験して調べる

先日の記事 www.rustforbeginners.com で、Fromの実装からIntoへの実装は定義されているが、逆は定義されていないことを確かめました。 そして、その理由として、型Tについて処理を定義しているモジュールの中でimpl XXX for Tを定義するならばXXXはIntoでは…

From実装からInto実装は自動生成されるが逆はされない

FromトレイトとIntoトレイトは、所有権を食べて他のオブジェクトに変換するトレイトです。これは、Derefトレイトのように自動的に変換されることはありませんが、AsRefトレイトのように、関数をより一般化するために定義されています。プログラミングRustに…

掛け算の順序問題をRustで解決する

掛け算の順序問題というのがあります。例えば、りんごが12個入った箱が3個あったら全部で何個でしょう?という問題に対して、12x3と答えるのが正しくて、3x12と答えるのは間違ってると指導される問題です。間違った順序で解答すると、バツがつけられることも…

Cursorの実装からrvalueを学ぶ

ReadのCursorインスタンスの実装を調べている時に、気になったことがあったので共有する。 以下に示す実装は、何でもいいから&[u8]を導けるもの(AsRef<[u8]>)をCursorでラップすればReadのインスタンスになれるという意味だ。実装としては、 www.rustforbegi…

変数がスタック上でどのように配置されているか実験して調べる

Rustでは、 Vecはデータをヒープに持ち、それへの所有権を持つ変数(ポインタ、キャパシティ、長さの3つの要素を持つ)がスタック上に配置される スライスはファットポインタ(ポインタと長さの2つの要素を持つ)で管理され、変数はスタック上に配置される そし…

IntoIteratorの前にDerefは呼ばれないことを実験で確かめる

昨日のブログ www.rustforbeginners.com の積み残し課題のために実験したら面白いことがわかったので共有します。バージョンは1.33.0-devです。 課題 実験 結果 考察 課題 &Vec<T>からIter<T>、&mut Vec<T>からIterMut<T>へのIntoIterator実装がVec<T>に対して行われている</t></t></t></t></t>…

IntoIteratorの実装を覗いてみる

pub trait IntoIterator { /// The type of the elements being iterated over. type Item; /// Which kind of iterator are we turning this into? type IntoIter: Iterator<Item=Self::Item>; fn into_iter(self) -> Self::IntoIter; } Rustのforループは、 for item in exp</item=self::item>…

ファットポインタがほしいなら、明示的に型づけすること

impl<T> ops::Deref for Vec<T> { type Target = [T]; fn deref(&self) -> &[T] { unsafe { let p = self.buf.ptr(); assume(!p.is_null()); slice::from_raw_parts(p, self.len) } } } Derefトレイトのおかげで、Rustは暗黙的に&Vec<T>から&[T]への変換を行ってくれ</t></t></t>…

メソッド呼び出しにおける参照解決アルゴリズムをざっくり理解する

Rustでは、様々な暗黙的型変換が行われる。 auto-referencing: メソッド呼び出しの&selfや&mut selfに対しては自動的に&や&mutをつけてくれる auto-dereferencing: 引数に対して型が合うまで無限に*をつけてくれる など、色々なことが出てきて、何をどう組み…

Readトレイトの実装からファットポインタを学ぶ

Readトレイトというのは、何かからデータを読み込むことを抽象化したトレイトです。もっとも基本的な実装はreadです。 pub trait Read { #[stable(feature = "rust1", since = "1.0.0")] fn read(&mut self, buf: &mut [u8]) -> Result<usize>; このうち、&[u8]型へ</usize>…