Open21

Rust入門

おーたにおーたに

printするときいちいち文字列変換のために "{}"つけないといけない?

fn main() {
    let a = 10;              
    println!(a); // error
    println!("{}", a); // ok
}

rubyだとだけでいいのに

a = 10
puts a

これは、暗黙の型変換を避けて、バグを防いだり、パフォーマンスと型安全を重視する観点からそうなってるっぽい。
なるほど

あと多分この仕様はrustに限った話じゃない

{}に変数展開されるということ

// const PI: f32 = 3.14159;

fn main() {
let pi = 3.14159;
   println!(
       "ゼロからアップル {} を作るには、まず宇宙を創造する必要があります。",
       pi
   );
=> ゼロからアップル 3.14159 を作るには、まず宇宙を創造する必要があります。

}

"{}"内に書くこともできる(ただ、直接関数はだめ)

fn main() {
    let a = 10;              
    println!("{a}"); // ok
}
おーたにおーたに

変数の変更

変数はほぼ型推論される。
q. 明示するのがが推奨か?
a. そんなことないっぽい?基本推論、可読性のために明示するなど良しなにやる感じで良さそう?

fn main() {
    let mut x = 42; // 可変可能
    let x = 42; //不変! errorになる
    println!("{}", x);
    x = 13;
    println!("{}", x);
}
おーたにおーたに

基本の型

8,32とは扱う数値の範囲か。
型から範囲がなんとなく予想つくのはちょっと面白い

こんな明示の仕方もあるらしい

 let a = 13u8;
println!("{}", a);
=> 13
おーたにおーたに

配列

fn main() {
    // let nums: [i32; 3] = [1, 2, 3];配列の数がわかっていれば 
    // let nums: Vec<i32> = vec![1, 2, 3];配列の数がわからない/変化する場合
    println!("{:?}", nums);
    println!("{}", nums[1]);
}
// [1, 2, 3]
// 2
おーたにおーたに

関数

fn add(x: u8, y: u8) -> u32 {
    // return x + y; error たとえ -> u32にしたとしても、asで明示する必要がある
    return (x as u32) + (y as u32);
}

fn main() {
    println!("{}", add(255, 1));
}

ちゃんと厳密だ!

おーたにおーたに

Rust の基本はそれほど難しくなかったですよね?

たし蟹

おーたにおーたに

enumとかstructは全然癖ないから、直感的にわかりそう
いいね

おーたにおーたに

メモリ管理

スコープの終わりをリソースのデストラクトと解放の場所として使用します。
このデストラクトと解放のことをドロップ (drop) と呼びます。

ガベージコレクション(GC)を使っていないので、厳密に不要となった瞬間解放される!

Q Rubyってどうなってる?
世代別GCが採用されてるらしい。
GPTの説明がわかりやすい。

あんまりメモリとか意識してなかったから、面白い!

GC誕生背景から考えるRustの特徴
GC誕生したのは主に下記問題で(多分)、それをRustではスコープの終わりに解放される仕組みであるため、開発者は意識することなく効率よく解放されるということ!

  1. 解放し忘れ
  2. 解放タイミングの難しさ

メモリ管理に関する注意点
循環参照(お互いを参照し合う)の場合、自動dropされない(?らしい)
明示的に解放が必要な場合もあること(もしくは自動でドロップされない処理を避ける)も少し気にしておいた方が良さそう

おーたにおーたに

所有権は、なかなか特徴的だなぁ

struct Foo {
    x: i32,
}
struct Foo {
    x: i32,
}
fn do_something(f: Foo) {
    println!("{}", f.x);
    // f はここでドロップ
}

fn main() {
    let foo = Foo { x: 42 };
    // foo の所有権は do_something に移動
    do_something(foo);
    // foo は使えなくなる
    println!("{}", foo.x); // error
}

で、所有権を移さずに使いたい(=値を借りる)時は、 &をつける

struct Foo {
    x: i32,
}

fn main() {
    let foo = Foo { x: 42 };
   // 所有権はfooのまま
    let f = &foo;
}

おーたにおーたに

参照外しも値を渡すという点で、*と同じでは?

↓なるほど。。
変数自体か実際の値かの違いみたいな

おーたにおーたに

Rustはフロントエンド・バックエンドどちらで使えるのか?

→どちらでも使える。

Rustはコンパイラ言語なので、基本サーバー言語の扱いだが、webアセンブリ(wasm)対応できるのでフロントでも動かせる。
そして、wasmを公式サポートしているため、他のコンパイラ言語 C/C++, Gonなどよりwasm導入しやすさがある