IDE としては VS Code を想定

sudo yum install -y gcc
bash -c "$(curl -fsSL https://raw.githubusercontent.com/mikanbox/dotfiles_centos/main/install.sh)"
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
cargo install cargo-watch

xの後にコマンドを自動実行できる

cargo watch -x check -x test -x run

VSCode の Rust-Analyzer は リリース版を使用することで、インテリセンスが有効になる

CLI を作成する機会があり、Rust がどうやらおすすめっぽいので使用することにした。 自分の悪い癖として、仕様を読まずに作り始めてしまう癖があるので、今回はなるべく事前に言語仕様を調べてから始めたいと思いここにまとめます。

What is Rust?

基本的には公式の FAQ が一番信頼性が高い。FAQ を見てざっくりまとめたものが以下。

  • 実行時の安全性が高い
  • 並列実行への全体的なサポート
  • 速い(C/C++ に近いパフォーマンスが出ることがベンチマークで実証)
  • 所有権の仕組みにより、GC なしでメモリ安全が保証
  • v1.63.0 (大規模なバージョンアップはされていない)

ビルドツール cargo

ビルドツールなので、パッケージ管理機能は弱いが、ライブラリ追加で補完できる

自動化

Rustfmt : フォーマッタ Clippy : たぶん、Lintツール Cargo Doc : JavaDoc みたいなドキュメント生成ツール

チュートリアル

https://www.rust-lang.org/ja/learn

標準ライブラリ

https://doc.rust-lang.org/std/index.html

std 名前空間が標準ライブラリ よって use std::hogehoge で使用可能 プリミティブ型(基本的な型: int とか) もここで紹介 std ライブラリは、プリミティブ型にメソッドを追加する唯一のライブラリ(継承とかしてる感じ?)

Option , Result モジュールはオプションとエラーハンドリングのタイプを定義

領域確保方法

  • Vec : ヒープに割り当てる可変領域
  • [T; N] : コンパイル時にサイズ固定できる配列 スタックに配置。 &[T;N]は銭湯のアドレスしか持たないので、参照サイズは小さい
  • Box<[T; N]> : ヒープに確保できる (Vecの方が良さそう。)
  • [T] 他の連続したストレージへの可変超サイズのスライス (?)

スライス:配列と同じような記述方法で、複数の要素を1つにまとめることができる Rust では配列の一部を借用するのに使う(コピーしたり、一部だけ参照したい時に使う?)

  • &[T] : 共有スライス
  • &mut [T] : 可変スライス
  • Box<[T]> : 所有スライス

配列とスライスの違い

https://doc.rust-jp.rs/rust-by-example-ja/primitives/array.html 配列はTという単一の型(訳注: ジェネリック型でも可)のオブジェクトの集合。メモリ上で連続領域に保存

スライス:配列と同じような記述方法で、複数の要素を1つにまとめることができる スライス : 配列に似ていますが、コンパイル時に長さが決定されていません。スライスは2ワードからなるオブジェクトであり、最初のワードがデータへのポインタ、2番目のワードがスライスの長さとなる。 おそらくヒープに格納される スライスは配列の一部を借用するのに使用され、&[T]という型シグネチャを持つ

str : UTF-8 の文字列スライスでプリミティブ型

スライスなので、通常は普遍の参照としてアクセスされ、結合とかはおそらく新変数になるっぽい

データは参照カウントボックスまたは型に配置することで共有できる(?) コレクションのモジュールはハッシュマップを持つ

基本的な OS とのやりとりはプラットフォーム依存なく、io/fs/net モジュールが使える

基本的な型 i8 / i16 / i32 / i64 / i128 符号付き整数 u8 / u16 / u32 / u64 / u128 符号付き整数 f32 / f64 unit usize / isize

ポインタ系 fn pointer

モジュール

ここにも, プリミティブ型が定義されている

マクロ

可変長の引数をとるやつとか、初期化とか

print println eprint eprintln

キーワード

as : キャストで使う async : 現在のスレッドをブロックすることを回避し、代わりに Future 型を返す await : Future 型が準備完了するまで待つ

extern :外部コードへのリンク or インポート : もう使わない。基本は use 使っとけ馬OK

所有権

https://doc.rust-jp.rs/book-ja/ch04-01-what-is-ownership.html スタックの方が速いけど、固定長じゃないといけない

原則

  • Rustの各値は、所有者と呼ばれる変数と対応している。
  • いかなる時も所有者は一つである。
  • 所有者がスコープから外れたら、値は破棄される。 →基本は宣言した人(というよりラベル、変数オブジェクトのこと?)が所有者なので、そのオブジェクトが宣言されたスコープから外れたら破棄される認識 関数の return とかの場合、所有権が移動する?それともコピーする?

具体例 文字列リテラル “hoge” は固定長なのでハードコードされメモリに乗る 変数は可変長なので、ヒープに載せる。以下でヒープに載せる命令を読んでいる String::from

Move 固定長の変数については、コピー時に所有権が移動する。 これは allocate / free が二重に起きないようにする仕組み コピーしたいなら clone できる

整数のようなコンパイル時に既知のサイズを持つ型は、スタック上にすっぽり保持されるので、 実際の値をコピーするのも高速

RustにはCopyトレイトと呼ばれる特別な注釈があり、 整数のようなスタックに保持される型に対して配置することができます

Copyの型の一部を並べておきます。

あらゆる整数型。u32など。 論理値型であるbool。trueとfalseという値がある。 あらゆる浮動小数点型、f64など。 文字型であるchar。 タプル。ただ、Copyの型だけを含む場合。例えば、(i32, i32)はCopyだが、 (i32, String)は違う。

値を返すことでも、所有権は移動します

参照

https://www.rust-lang.org/ja https://prev.rust-lang.org/ja-JP/faq.html