Code Fix

中級

E0277: doesn't implement `std::fmt::Display` の原因と直し方

自作の構造体を{}(Display)で出力しようとすると、Displayトレイトを実装していない限りE0277エラーになります。デバッグ目的で中身を見たいだけなら、{:?}(Debug)を使う方法もあります。

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

error[E0277]: `Point` doesn't implement `std::fmt::Display`
E0277
エラーコード — `rustc --explain E0277` で詳しい説明が見られます
`Point` doesn't implement `std::fmt::Display`
詳細メッセージ — 何が問題だったか

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

パターン1

 1  #[derive(Debug)]
 2  struct Point { x: i32, y: i32 }
 3  fn main() {
 4      let p = Point { x: 1, y: 2 };
 5      println!("{}   ", p);
                    ^
 6  }
error[E0277]: `Point` doesn't implement `std::fmt::Display`

deriveしたのはDebugだけなので、{}(Display)ではなく{:?}(Debug)を使う必要があります。

直し方: {}{:?} にします。

この問題を解いてみる →

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

パターン2

 1  #[derive(Debug)]
 2  struct Item { name: String, price: i32 }
 3  fn main() {
 4      let it = Item { name: String::from("pen"), price: 100 };
 5      println!("{}   ", it);
                    ^
 6  }
error[E0277]: `Item` doesn't implement `std::fmt::Display`

自作の構造体はDisplayを自分で実装しない限り{}では表示できません。デバッグ目的なら{:?}を使います。

直し方: {}{:?} にします。

この問題を解いてみる →

パターン3

 1  #[derive(Debug)]
 2  struct User { id: i32, name: String }
 3  fn main() {
 4      let u = User { id: 1, name: String::from("taro") };
 5      println!("{}   ", u);
                    ^
 6  }
error[E0277]: `User` doesn't implement `std::fmt::Display`

#[derive(Debug)]はDebugトレイトだけを自動実装します。Displayは含まれません。

直し方: {}{:?} にします。

この問題を解いてみる →

パターン4

 1  #[derive(Debug)]
 2  struct Box2D { w: i32, h: i32 }
 3  fn main() {
 4      let b = Box2D { w: 3, h: 4 };
 5      println!("{}   ", b);
                    ^
 6  }
error[E0277]: `Box2D` doesn't implement `std::fmt::Display`

構造体をそのまま人間向けに整形して表示したい場合は、Displayトレイトを自分で実装する必要があります。

直し方: {}{:?} にします。

この問題を解いてみる →

パターン5

 1  #[derive(Debug)]
 2  struct Coord { lat: f64, lng: f64 }
 3  fn main() {
 4      let c = Coord { lat: 35.6, lng: 139.7 };
 5      println!("{}   ", c);
                    ^
 6  }
error[E0277]: `Coord` doesn't implement `std::fmt::Display`

{}と{:?}はどちらもトレイトに基づく表示方法で、実装されていない方を使うとコンパイルエラーになります。

直し方: {}{:?} にします。

この問題を解いてみる →

よくある誤解

「構造体はフィールドを持っているのだから、printlnで自動的に中身が表示されるはず」という思い込みは誤りです。表示方法(DisplayやDebug)はトレイトとして明示的に実装するか、deriveで自動導出する必要があります。

まとめ

E0277: doesn't implement `std::fmt::Display`は中級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

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