Question
I tried to print a Rust vector using println!("{}", v2), but the compiler reports that Vec<T> does not implement std::fmt::Display.
fn main() {
let v2 = vec![1; 10];
println!("{}", v2);
}
The compiler error says:
error[E0277]: `std::vec::Vec<{integer}>` doesn't implement `std::fmt::Display`
--> src/main.rs:3:20
|
3 | println!("{}", v2);
| ^^ `std::vec::Vec<{integer}>` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `std::vec::Vec<{integer}>`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: required by `std::fmt::Display::fmt`
Why does this happen, and is Display implemented for Vec<T>? If not, how should a vector be printed in Rust?
Short Answer
By the end of this page, you will understand why Vec<T> cannot be printed with {} in Rust, when to use {:?} instead, and how Display differs from Debug. You will also learn practical ways to print vectors, including pretty-printing and creating custom output when you want a human-friendly format.
Concept
Rust has two common formatting traits for printing values:
Display→ for user-facing, clean output with{}Debug→ for developer-facing output with{:?}
A Vec<T> implements Debug, but not Display.
That means this works:
let v = vec![1, 2, 3];
println!("{:?}", v);
But this does not:
let v = vec![1, 2, 3];
println!("{}", v); // error
Why Vec<T> does not implement Display
Mental Model
Think of Display and Debug as two different labels on a printer:
Display= show this nicely to a userDebug= show this clearly to a programmer
A Vec<T> is like a box full of items. If someone says, "print the box nicely," Rust asks: what does nicely mean?
- As a comma-separated list?
- As JSON-like text?
- As a vertical list?
There is no single best answer, so Rust refuses to guess for Display.
But for debugging, a standard inspected form is fine, so Debug prints the contents in a consistent developer-friendly way.
Syntax and Examples
The most important syntax is:
println!("{:?}", value); // Debug
println!("{:#?}", value); // Pretty Debug
println!("{}", value); // Display
Printing a vector with Debug
fn main() {
let v = vec![1, 2, 3];
println!("{:?}", v);
}
Output:
[1, 2, 3]
Pretty-printing a vector
fn main() {
let v = vec![1, 2, 3];
println!("{:#?}", v);
}
Output:
Step by Step Execution
Consider this example:
fn main() {
let v = vec![1, 2, 3];
println!("{:?}", v);
}
Step by step
vec![1, 2, 3]creates aVec<i32>.println!sees the format string"{:?}".{:?}tells Rust: use theDebugtrait.Vec<i32>implementsDebug, so formatting succeeds.- Rust prints the vector in debug form:
[1, 2, 3].
Now compare it with this failing version:
fn main() {
let v = vec![1, 2, 3];
(, v);
}
Real World Use Cases
Printing vectors appears in many practical Rust tasks:
Logging intermediate data
When debugging APIs, parsers, or algorithms, developers often inspect vectors:
println!("Parsed tokens: {:?}", tokens);
Inspecting query or processing results
A function may return a list of records, IDs, or errors:
println!("Matching IDs: {:?}", ids);
Pretty-printing nested data during development
When vectors contain structs or nested collections, {:#?} is easier to read:
println!("{:#?}", results);
Building user-facing output
If you are printing data for users, you usually do not rely on Debug. Instead, you format the output explicitly:
let names = vec!["Alice", "Bob", "Cara"];
println!("Users: {}", names.join());
Real Codebase Usage
In real Rust codebases, developers usually follow these patterns:
Use Debug for quick inspection
During development, Vec<T> is often printed with {:?} in:
- temporary debugging statements
- tests
- logs
- prototypes
dbg!(&items);
println!("Loaded items: {:?}", items);
Format user output explicitly
For command-line tools or messages shown to users, teams usually choose a deliberate format:
let output = values
.iter()
.map(|v| v.to_string())
.collect::<Vec<_>>()
.join(", ");
println!("Values: {}", output);
Use wrapper types for reusable formatting
If the same vector formatting is needed in many places, a wrapper type is common:
struct CsvVec<T>(Vec<T>);
Then can be implemented once and reused.
Common Mistakes
Mistake 1: Using {} for a vector
Broken code:
fn main() {
let v = vec![1, 2, 3];
println!("{}", v);
}
Why it fails:
{}requiresDisplayVec<T>does not implementDisplay
Fix:
println!("{:?}", v);
Mistake 2: Assuming Debug is good for user-facing output
This works:
println!("{:?}", vec!["Alice", "Bob"]);
But the output may not be the style you want for end users.
Better:
Comparisons
| Feature | Display | Debug |
|---|---|---|
| Placeholder | {} | {:?} |
| Purpose | User-facing output | Developer-facing output |
| Intended style | Clean, readable | Inspectable, diagnostic |
Implemented for Vec<T> | No | Yes |
| Pretty-print option | No built-in equivalent | {:#?} |
| Good for logs/tests | Sometimes | Yes |
| Good for final CLI/UI text |
Cheat Sheet
println!("{}", value)usesDisplayprintln!("{:?}", value)usesDebugprintln!("{:#?}", value)uses prettyDebugVec<T>implementsDebugVec<T>does not implementDisplay- You cannot implement
DisplayforVec<T>directly because of Rust's orphan rules - For custom vector output:
- format elements manually
- or create a wrapper type and implement
Display
Common patterns
let v = vec![1, 2, 3];
println!("{:?}", v);
println!("{:#?}", v);
FAQ
Why can't I print a Vec with {} in Rust?
Because {} requires the Display trait, and Vec<T> does not implement Display.
How do I print a vector in Rust?
Use {:?} for debug output:
println!("{:?}", my_vec);
What is the difference between Display and Debug in Rust?
Display is for clean user-facing output. Debug is for programmer-facing inspection.
Can I implement Display for Vec<T> myself?
No, not directly. Rust's orphan rules prevent implementing a foreign trait for a foreign type. Use a wrapper type instead.
What does {:#?} do in Rust?
It pretty-prints Debug output across multiple lines, which is useful for complex or nested data.
Mini Project
Description
Build a small Rust program that prints a list of tasks in two ways: a developer-friendly debug view and a clean user-facing view. This demonstrates when to use Debug and when to build custom formatting instead of relying on Display for Vec<T>.
Goal
Create a program that stores tasks in a vector, prints the raw vector with Debug, and then prints a custom comma-separated string for users.
Requirements
- Create a vector of at least three task names.
- Print the vector once using
{:?}. - Print the tasks again in a user-friendly comma-separated format.
- Include a wrapper type or helper function for reusable formatting.
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Associated Types vs Generic Type Parameters in Rust: When to Use Each
Learn when to use associated types vs generic parameters in Rust traits, with clear rules, examples, and practical API design advice.
Can a Struct Extend Another Struct in Rust? Composition vs Inheritance
Learn how Rust handles struct reuse without inheritance, using composition, traits, and wrapper structs with practical examples.