Code Fix

初級

E0369: cannot add `&String` to `&str` の原因と直し方

文字列リテラル(&str)を左側にして+で連結しようとすると、+演算子がStringの左辺にしか実装されていないためE0369エラーになります。

エラーメッセージの読み方

error[E0369]: cannot add `&String` to `&str`
E0369
エラーコード — `rustc --explain E0369` で詳しい説明が見られます
cannot add `&String` to `&str`
詳細メッセージ — 何が問題だったか

このエラーが出る典型パターン

パターン1

 1  fn main() {
 2      let name = String::from("world");
 3      let msg = "hello, "             + &name;
                            ^
 4      println!("{}", msg);
 5  }
error[E0369]: cannot add `&String` to `&str`

+演算子はStringの左辺にしか実装されていません。文字列リテラルを左に置くにはto_string()で変換します。

直し方: "hello, " を "hello, ".to_string() にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  fn main() {
 2      let city = String::from("osaka");
 3      let msg = "welcome to "             + &city;
                              ^
 4      println!("{}", msg);
 5  }
error[E0369]: cannot add `&String` to `&str`

左辺が&str(文字列リテラル)のままだと+演算子が定義されておらずコンパイルエラーになります。

直し方: "welcome to " を "welcome to ".to_string() にします。

この問題を解いてみる →

パターン3

 1  fn main() {
 2      let item = String::from("apple");
 3      let msg = "buy "             + &item;
                           ^
 4      println!("{}", msg);
 5  }
error[E0369]: cannot add `&String` to `&str`

所有権を持つString同士なら連結できますが、リテラルのままの&strは+の左辺になれません。

直し方: "buy " を "buy ".to_string() にします。

この問題を解いてみる →

パターン4

 1  fn main() {
 2      let team = String::from("tigers");
 3      let msg = "go "             + &team;
                          ^
 4      println!("{}", msg);
 5  }
error[E0369]: cannot add `&String` to `&str`

to_string()やString::from()でリテラルを所有権付きの文字列に変換すれば+が使えます。

直し方: "go " を "go ".to_string() にします。

この問題を解いてみる →

パターン5

 1  fn main() {
 2      let day = String::from("monday");
 3      let msg = "happy "             + &day;
                            ^
 4      println!("{}", msg);
 5  }
error[E0369]: cannot add `&String` to `&str`

他の言語の+のように何でも連結できるわけではなく、Rustでは左辺の型が限定されています。

直し方: "happy " を "happy ".to_string() にします。

この問題を解いてみる →

よくある誤解

「+は文字列同士ならどちらが左でも連結できるはず」という思い込みは誤りです。+はStringの左辺にしか実装されておらず、左側を所有権を持つStringにする必要があります。

実務での勘所

この非対称の正体は、+の実体がString型に対してimpl Add<&str> for Stringという形で1パターンだけ実装されているためです。この実装は左辺のStringの所有権を消費し(ムーブし)、既存のヒープ上のバッファを可能な限り再利用しながら右辺の&strを追記して、新しいStringを返します。所有権を持つ左辺がある前提の実装なので、左辺が借用でしかない&strでは、この操作を安全に行う権利がそもそもありません。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)