所有権の「コピー」について

Rustでは変数に所有権がありますが、先述の通り「数値」を代入した変数は「コピー」されるので所有権を気にする必要はありません。例えば、図3とサンプルコードのように数値を代入した変数を書けばエラーが出ません。

数値のコピーは複数のデータを持つ必要がなく、アドレスを持つことと同じ1個だけの型の変数を持てば良いので、ムーブしても所有権の概念は必要ないからです。

図3:所有権の「コピー」

・所有権のコピーのサンプルコード
fn main() {
    let good1 = 0;
    let good2 = good1;
    println!("{}",good1); // エラーなし
    println!("{}",good2); // エラーなし
}

【サンプルコードの解説】
「good1」変数に数値「0」を代入して宣言します。
「good2」変数に「good1」変数をコピーします。
「good1」変数をターミナルに表示します。
「good2」変数をターミナルに表示します。

所有権と「関数」について

変数を関数の引数に渡しても所有権のムーブが起こります。すると図4とサンプルコードのようにムーブした元の「good1」変数にはもう所有権が残っていないため、「good1」変数を使おうとするとエラーが起こります。

このエラーを回避するには「先述と同じclone()関数でクローンするように」とターミナルにエラーメッセージが出ます。次のサンプルコードでエラーを回避するには「good_str(good1);)」→「good_str(good1.clone());」と書き換えクローンを使います。

図4:所有権と「関数」

・所有権と関数のサンプルコード
fn main() {
    let good1 = String::from("Good");
    good_str(good1); // → good_str(good1.clone());
    println!("{}",good1); //エラー
}

fn good_str(_good: String) {
}

【サンプルコードの解説】
「good1」変数に"Good"を代入して宣言します。
「good_str」関数にgood1を引数として渡します。「_good」引数の最初に「_(アンダーバー)」が付いているのは、関数内でこの引数を使わないことを表しています。
ターミナルにgood1の文字列を表示しようとするとエラーが出ます。

所有権と「関数の戻り値」について

関数内の変数から所有権をムーブするには、図5とサンプルコードのように「good_str」関数内で宣言された変数の所有権を「戻り値」で受け取れば「good1」変数に所有権が渡ります。

ところで、例えば「good_str」関数の戻り値の書式は、関数の最後で「;」なしの「good」か、一般の他のプログラミング言語と同じく「return good;」のように書きます。

図5:所有権と「関数の戻り値」

・所有権と関数の戻り値のサンプルコード
fn main() {
    let good1 = good_str();
    println!("{}",good1); // エラーなし
}

fn good_str() -> String {
    let good = String::from("Good");
    good
}

【サンプルコードの解説】
「good_str」関数で「good」変数に"Good"文字列を代入し、戻り値「good」を「good1」変数に代入します。
「good1」変数をターミナルに表示します。

所有権と「関数の引数と戻り値」について

関数に引数を渡してもクローンを使わずにムーブだけで元の変数「good1」を使えるようにするには、図6とサンプルコードのように「good1」引数をmut(変数の値を変更可能)にして関数に渡した引数を「戻り値」で受け取るようにします。

なお「good_str」関数から渡した「good1」引数の所有権を「戻り値」で受け取れば、再度「good1」変数に所有権が返ります。

図6:所有権と「関数の引数と戻り値」

・所有権と関数の引数・戻り値のサンプルコード
fn main() {
    let mut good1 = String::from("Good");
    good1 = good_str(good1);
    println!("{}",good1); // エラーなし
}

fn good_str(good: String) -> String {
    return good;
}

【サンプルコードの解説】
「good1」変数に"Good"を代入してmutでミュータブルに宣言します。
「good_str」関数の引数にgood1変数を渡し、戻り値をgood1変数に代入します。
「good1」変数をターミナルに表示します。

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30