JavaやJavaScriptなどでは、ヒープ領域に確保したメモリは誰からも参照されなくなった後にガーベジコレクションによって解放される。Rustでは、ただ一つの変数がヒープ上のメモリの所有権を持ち、所有者がスコープから消えた時点でヒープ領域も解放される。
fn func1() {
let name = String::from("ABC");
println!("{}", name);
}
関数に変数を渡すと所有権が移る
fn func1() {
let name = String::from("ABC");
println!("{}", name);
func2(name);
println!("{}", name);
}
fn func2(name: String){
println!("{}", name);
}
所有権を返してもらうこともできる
fn func1() {
let name = String::from("ABC");
println!("{}", name);
name = func2(name);
println!("{}", name);
}
fn func2(name: String) -> String{
println!("{}", name);
name
}
&で参照を渡すことで、所有権を移さないまま関数を呼び出すこともできる
fn func1() {
let name = String::from("ABC");
println!("{}", name);
name = func2(&name);
println!("{}", name);
}
fn func2(name: &String){
println!("{}", name);
}
関数内で他の変数に渡しただけでも所有権の移転が発生する
fn func1() {
let s1 = String::from("ABC");
{
let s2 = s1;
println!("{}", s2);
}
}
c++でお馴染みのswap
#include <cstdio>
void swap(int &a, int &b)
{
int temp;;
temp = a;
a = b;
b = temp;
}
void swap_pointer(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5;
int y = 8;
swap(x, y);
printf("%d, %d\n", x, y);
swap_pointer(&x, &y);
printf("%d, %d\n", x, y);
return(0);
}
rustでswapを書こうとすると上手くいかない
fn func1() {
let s1 = String::from("ABC");
{
let s2 = s1;
println!("{}", s2);
}
}
fn func2(name: &String){
println!("{}", name);
}
fn main(){
let mut x: i32 = 5;
let mut y: i32 = 8;
swap(&x, &y);
println!("x:{} y:{}", x, y);
}
$ ./main
x:5 y:8