Rustコトハジメ

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

The fact that closure's super traits are generated by compiler

In the previous post, we have learned that closure is generated by the compiler (e.g. The compiler generates a class implements FnMut for a closure that mutates the captured environment) but how super traits for the closure is generated wa…

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

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

Why do Iterator methods take FnMut instead of Fn?

Rust iterator supports functional programming that is, it supports functions like map and 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, F: FnMut(B,</b,></self,></b,>…

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,>…

Smart pointers in Rust

https://www.rustforbeginners.com/entry/en/2018/12/29www.rustforbeginners.com In the post above, I mentioned the Vec is a ownership pointer that has three members. In Rust, pointer-like stuffs which has internal special metadata are called …

Arc<Mutex<T>> is a design pattern in Rust

Rust has no GC and you can't write some kind of code that you ever wrote in other languages. The typical case is recursive data structures like list, tree and graph. By looking for documents or articles, you will find types like the follow…

How reference of integer is able to add

Are you surprised by this code? If you are a C/C++ programmer you should be. fn main() { let a = 5; let b = 3; println!("{},{},{},{}", a+b, a+&b, &a+b, &a+&b) } To surprise the output is 8,8,8,8 The trick behind this behavior is macros: Ar…

Learn a lot from Index trait

fn main() { let mut v = vec![1, 2, 3, 4, 5]; let a = &v[0]; v.push(6); } If you try to compile this code error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable --> prog.rs:4:5 | 3 | let a = &v[0]; | - immutable…

Closure in Rust is generated by the compiler

The three types of closure in Rust Mix immutable borrow and mutable borrow in closure Discussion TODO The three types of closure in Rust In Rust, compiler generates distinct class for each closure in code and they implements Fn or FnMut or…

Zero cost abstraction explained

The first time I heard the word "Zero cost abstraction" I had no idea what it is. In the same way I could not soon understand why GC is not needed while free is not needed at the same time, I was confused what zero cost of abstraction is. …

Introduce Wandbox - A good service to learn the spec -

When learning Rust you often want to write some small program to experiment. In this case, I use a service called Wandbox made by a Japanese. [Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ There is another alternative called Ideone which is more famous glo…

Into to From blanket implementation is not possible

In the previous post https://www.rustforbeginners.com/entry/en/2019/01/01www.rustforbeginners.com we have confirmed that there is a blanket implementation impl Into for From but there is none for the opposite. In the post, I explained the …

Into implemented from From but not the opposite

From trait and Into trait are traits that takes an ownership of a object to make another object. They are not implicitly used by the compiler like Deref trait but widely exploited to write more generalized code as like AsRef trait. In Prog…

Learn rvalue from Cursor implementation

In this article, I will share a nice finding when I explore the Cursor implementation of Read trait. The implementation below means that anything which can lead &[u8] (AsRef<[u8]>) can be an instance of Read by wrapping it by Cursor. The i…

How pointers are placed in stack

In Rust, Vec has a data on the heap and the ownership pointer has three metadata (pointer, capacity and the length) and placed on the stack. Slice is a fat pointer with two members (pointer and length) and placed on the stack. And data wil…

Deref is not called before IntoIterator

In the previous post https://www.rustforbeginners.com/entry/en/2018/12/27www.rustforbeginners.com we left a question. And this post is the answer. I will share the interesting finding from a simple experiment. The question Experiment Resul…

IntoIterator implementations explored

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; } For-looping in Rust is like this: f</item=self::item>…

Explicit typing is required to get a fat pointer

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) } } } We know that Rust implicitly convert &Vec<T> to &[T] thanks to Deref trait.</t></t></t>…

Understand the reference resolution rule in Rust

There is a lot of implicit type conversions in Rust. Some of them are auto-referencing: Rust compiler add & or &mut automatically to the &self or &mut self in method call. auto-dereferencing: Rust compiler dereferences type by adding * unt…

Learn fat pointer from Read trait

Read trait is a trait that abstracts reading something from somewhere and the core method is the read. Let's see the type. pub trait Read { #[stable(feature = "rust1", since = "1.0.0")] fn read(&mut self, buf: &mut [u8]) -> Result<usize>; The imp</usize>…

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

https://www.rustforbeginners.com/entry/ja/2018/12/29www.rustforbeginners.com で、Vecは3つのデータを持つ構造だと言った。そして、この時には所有権を持つ者ということで所有者という言葉を使った。 このように、内部に特殊なメタデータを持つポインタ…

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不要と書いてあって何を言ってるのかさっぱりわからなかったのと同様に、抽象化のコストがゼロ…

言語仕様の勉強にはWandboxがオススメ

Rustを勉強していると、私も今そうなのですが、実際に小さな実験コードを書いて試したいということがよくあります。そういう時に、私はWandboxというサービスを使っています。これは日本人の方が作っているサービスです。 [Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ 有…

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

先日の記事 https://www.rustforbeginners.com/entry/ja/2019/01/01www.rustforbeginners.com で、Fromの実装からIntoへの実装は定義されているが、逆は定義されていないことを確かめました。 そして、その理由として、型Tについて処理を定義しているモジュ…

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

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

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

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