開発者がもっとも好きなプログラミング言語 1 位 Rustに入門してみる

Rustに入門してみる

Rustとは
- 2015(最近!)にリリースされた言語
- 静的型付け
- C/C++の代わりになる次世代言語
- 鬼ほど実行スピードが速い(最速言語のC/C++と同等)
- C/C++の弱みであるメモリ安全性がRustでは保証されている
- コンパイルが通る=メモリ安全性が保証
-
C/C++の重大セキュリティ脆弱性の70%はメモリ安全性に起因する

Rust すげぇ
- 速い
- GAFAMが採用、後押し
- Google: AndroidやLinuxと言った基底のシステムにも採用される
- 2021/04から
- Microsoft: Windows10から部分的にC/C++からRustへ置き換え
- Rust Foundamationの顔ぶれが強すぎる
- AWS
- HUAWEI
- Microsoft
- moz://a
- Google: AndroidやLinuxと言った基底のシステムにも採用される

モジュールのインポート・エクスポート
親モジュール
mod module_name;
で取り込む
(typescriptのimport
みたいな)
module_name::func_name
で実行
子モジュール
pub fn run()
みたいにpub
をつける
('typescriptのexport
みたいな)

module_name.rs
の同じ階層にmodule_name
のフォルダを作るとサブモジュール
として定義できる

vars.rs
からvars/sub_a.rs
を読み込む
mod sub_a;
親階層ではprivateがデフォルトなので、やはりpub
を付与する
pub mod sub_a;

Rustはどうやらメモリ管理部分に新規性があるので、
そこを理解するのが肝らしい

メモリの種類
LIFOで高速
- Heap:可変
- Stack:固定サイズ
- Static:const, 文字リテラル
- Text: コード

Stack
let
を使用
let a = 10;
let b = 20;
スコープを抜けるとメモリ解放

ポインタ
(心の声やりたくねぇ、ポインタ嫌い)
64bit OS = 8 bytes
32bit OS = 4 bytes
自由にアクセス可能

int
i8 - i128まである
(128!?っていつつかうんだよ)

表記
Decimalでアンダーバー使える
(そういえばtypescriptでも最近使えるようになっていたなぁ)

float
デフォルトでf64
: f32
で定義することも可能

floatの精度気になったので見てみる
f32で精度的には7桁程度らしい
パフォーマンスの相当のこだわりがなければデフォルトのf64を使っておくのが無難か
長いリストデータをつかうときはこだわったほうがメモリ効率が良さそう
Floating Point Primitive Data Types
Type Size Range Accuracy
float 32 bits -3.4E+38 to +3.4E+38 about 7 decimal digits
double 64 bits -1.7E+308 to +1.7E+308 about 16 decimal digits

rustのlet
がtypescriptのconst
rustのlet mut
がtypescriptのlet
let x = 5;
x = 6;
let x = 5;
x = x + 1;

const
はファイルのグローバルで定義できる
const MAX_POINTS: u32 = 100_000;

&
でポインタにアクセス
&MAX_POINTS

同じ名前の変数名で定義してもメモリは別になるので、パフォーマンスが上がるわけではなさそう

{}でスコープを切れる
{
}

tupleのアクセスはドット
t.0, t.1, t.2など

*
で参照外し
let mut t2 = ((0,1),(2,3))
let ((ref mut x1_pointer, rf mut y1_pointer),_) = t2
*x1_pointer = 5;

配列
固定長なので長さは変更不可
コンパイル時に決まる
let a = [1,2]
a[1]

文字列(&str固定長)
Stack領域に入る
UTF-8が採用されている(素晴らしい)
&str
型となる
let s1 = "test";
文字列のメモリ
- 参照データ
- 実データ
に分かれる
文字列のメモリ詳細
- 参照データ
- ptr: 8byte
- len: 8byte
- 実データ
- 静的領域

文字列 (str可変長)
Heap領域に入る
let mut s2 = String::from("test");
文字列のメモリ詳細
- 参照データ
- ptr: 8byte
- len: 8byte
- cap: 8byte
- rustが自動的に余裕を持った領域を確保
- 実データ
- 静的領域

所有権
(肝の話きたー)
所有権の概念
- 2重開放エラー
s1とs2が同じHeapを参照している状態
s1が役目を終えると、Heapを開放
s2はまだ使っているのに、、、

文字列スライス(固定長)の場合は所有権がない
静的領域にあって、開放の必要がないから

リスト固定長
スタックは8MB制限あり
あまり大きなデータは格納できない

リスト可変長
ベクター型
vec!

BOXポインター
例・ノード内
数字
ノード
BOXポインター化すれば、8バイトと決まり
コンパイルエラーを起こさなくなる