2026-09-18
concat_move.rs
fn main() {
let hello = String::from("Hello, ");
let world = String::from("world!");
let combined = hello + &world;
println!("{combined}");
println!("{hello}");
}
これはコンパイルできるでしょうか?できないならどこが問題でしょうか?
Answer
コンパイルできません。Stringの+(impl Add<&str> for String)は左側を参照ではなく値として受け取り、そのString自身のバッファに右側を追記して返します。新しいメモリを毎回確保しないためにこの所有権を消費する設計になっているので、hello + &worldはhelloの所有権をcombinedへムーブします。ムーブしたあとのhelloを2つ目のprintln!で使おうとしているので、コンパイルエラー(borrow of moved value)になります。もう一度使いたいなら、先にhello.clone()するか、+ではなくformat!("{hello}{world}")のように借用だけで済む書き方にします。