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パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。