「TAURI」を使う前に、まず「Rust」の所有権を理解する
所有権の「コピー」について
Rustでは変数に所有権がありますが、先述の通り「数値」を代入した変数は「コピー」されるので所有権を気にする必要はありません。例えば、図3とサンプルコードのように数値を代入した変数を書けばエラーが出ません。
数値のコピーは複数のデータを持つ必要がなく、アドレスを持つことと同じ1個だけの型の変数を持てば良いので、ムーブしても所有権の概念は必要ないからです。
・所有権のコピーのサンプルコード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());」と書き換えクローンを使います。
・所有権と関数のサンプルコード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;」のように書きます。
・所有権と関数の戻り値のサンプルコード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」変数に所有権が返ります。
・所有権と関数の引数・戻り値のサンプルコード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」変数をターミナルに表示します。