変数aに文字列「これはテストです.」があり,これを変数bにコピーする,という動作には3つの選択肢があります.
aとbが同じオブジェクトを参照する
代表的な言語はPythonです.
a = "これはテストです." b = a print("a={}, id={}".format(a, id(a))) print("b={}, id={}".format(b, id(b)))
これを実行すると,下記のようになります.aとbが同じオブジェクトを参照していることが分かります.
a=これはテストです., id=1933243856048 b=これはテストです., id=1933243856048
ただし,複数の変数が同じオブジェクトを参照していると,オブジェクトを開放するタイミングが複雑になります.
a = "これはテストです." b = a print("a={}, id={}".format(a, id(a))) del a # aを開放 print("b={}, id={}".format(b, id(b)))
変数aを削除する行を追加しました.
a=これはテストです., id=2623329744048 b=これはテストです., id=2623329744048
変数bの参照が残っているので,変数aを削除する際に,文字列「これはテストです.」を開放できない状況です.Pythonはこれをうまく処理してくれます.
そんなややこしいことはするなとエラーにする
Rustではエラーになります.
fn main() { let a: String = String::from("これはテストです."); let b = a; println!("a = {}", a); println!("b = {}", b); }
これを実行すると,コンパイル時にエラーとなります.
error[E0382]: borrow of moved value: `a`
Rustでは1つのオブジェクトの所有権は1個だけ,という規則があり,安全なメモリ管理をしています.
オブジェクトを複製する
上記の例を実行するには,明示的にオブジェクトを複製します.
fn main() { let a: String = String::from("これはテストです."); let b = a.clone(); // 複製 println!("a = {}", a); println!("b = {}", b); }
正常に実行されます.
a = これはテストです. b = これはテストです.