🦀

Rustの勉強3

2024/08/12に公開

こんにちは!kirigayaです。
この記事を書いているタイミングは夏休みです!
ダラダラしているともったいないのでしっかり記事書いてアウトプットしていきます。
今回は3回目の記事です。(・ω・)

printの違い

print!()
テキストを改行なしで出力します。

print!("こんにちは");
print!("こんばんは");

println!()
テキストを出力した後、自動的に改行します。

println!("こんにちは");
println!("こんばんは");

変数のスコープ

  • スコープ (Scope):
    スコープとは、変数が有効である範囲を指します。Rustでは、スコープが終了すると、そのスコープ内で作成された変数は自動的に破棄されます。
    変数がスコープを抜けると、Rustの所有権システムにより、その変数が所有していたメモリが自動的に解放されます。

ブロック{}を使って変数のスコープを決めることができます。
pythonでは同じ変数名作ると上書きされてしまいますが
Rustは適切にブロックを作ることで同じ変数名でも違う値を保持できます。
実行結果は10,100,10です。

fn main(){
    {
        let n: i32 = 10;
        println!("{n}");
        {
            let n: i32 = 100;
            println!("{n}")
        }
        println!("{n}")
    }
}

drop関数

drop関数を使って手動でメモリを解放することができます。
※手動で行う必要はない...

fn main() {
    let s = String::from("hello");

    // 変数 s がスコープを抜ける前に手動でメモリを解放
    std::mem::drop(s);
    // s はすでに解放されているため、コンパイルエラー
    println!("{}", s); 
}

所有権の移動

Rustの所有権システムの基本概念

  • 所有権 (Ownership):
    Rustでは、各値には「所有者」と呼ばれる変数が存在します。変数がその値の所有者である限り、その値のメモリにアクセスすることができます。
    ある時点で、特定の値にはただ一つの所有者しか存在しません。

  • 借用 (Borrowing):
    所有権を持つ変数から他の変数にその値を借りることができます。このとき、借りる側は所有権を持たないため、借りた値を変更することはできません(不変借用)。ただし、ミュータブルな借用であれば、借りた側でも値を変更できますが、その場合、同時に他の借用が存在しないことが保証されます。

fn main(){
    let s1 = String::from("hello");
    let s2 = s1;  // s1の所有権がs2にムーブ(移動)
    // s1は無効化されているため、コンパイルエラー
    println!("{}", s1);
}

コンパイル時の振る舞いを指定する

  • deny(拒絶) コンパイラはエラーメッセージを出し実行可能なコードを生成しない
#[deny(unused_variables)]
fn main(){
    let x: i32 = 1;
}
  • warn(警告) コンパイラは警告メッセージを出し実行コードを生成する
#[warn(unused_variables)]
fn main(){
    let x: i32 = 1;
}
  • allow(許可) コンパイラは、全くメッセージを出さず実行コードを生成する
#[allow(unused_variables)]
fn main(){
    let x: i32 = 1;
}

多次元配列

1が4個入った配列を3つ作成します。

fn main(){
    let x: [[i32; 4]; 3]= [[1; 4]; 3];
    println!("{:#?}", x);  // 多次元配列を階層的に表示
}

ndarray::Array3を使う場合
Cargo.toml に依存関係を追加
まず、Cargo.toml に ndarray クレートを追加します。最新のバージョンを使うためには、バージョン番号を確認して記入します。

[dependencies]
ndarray = "0.15"  # または最新の安定バージョンを使用

一番綺麗に表示される...多分

use ndarray::Array3;

fn main() {
    // 15x8x4 の3次元配列を作成
    let x = Array3::<i32>::from_elem((2, 2, 2), 1);

    // 配列を表示
    println!("{:?}", x);
}

値を取り出す。
※インデックスへの直接参照はサポートされていない...
array1[0][0]

use ndarray::Array2;

fn main() {
    // 2x2 の配列を作成し、0 と 1 を設定
    let array1: Array2<i32> = Array2::from_shape_vec((2, 2), vec![0, 1, 1, 0]).unwrap();

    println!("{:?}", array1);
    println!("{}", array1.get((0,0)).unwrap());
    println!("{}", array1.get((1,0)).unwrap());

}

今回はここまでです!お疲れ様でした...

岩田組

Discussion