Reputation: 19724
I have the following:
{
let mut v = vec![1, 2, 3, 4, 5];
{
println!("v = {}", v);
let first = &v[0];
println!("The first element is: {}", first);
}
v.push(6);
{
println!("v = {}", v);
let first = &v[0];
println!("The first element is: {}", first);
}
}
And my error is:
println!("v = {}", v);
^ `Vec<{integer}>` cannot be formatted with the default formatter
`Vec<{integer}>` doesn't implement `std::fmt::Display`
help: the trait `std::fmt::Display` is not implemented for `Vec<{integer}>`
That seems straightforward. I will follow the error message and implement the fmt interface for a vector of integers, as suggested:
use std::fmt;
impl fmt::Display for Vec<integer>{
fn fmt(&self) {
for i in self.iter() {
println!("{}", i);
}
}
}
let mut v = vec![1, 2, 3, 4, 5];
{
println!("v = {}", v);
let first = &v[0];
println!("The first element is: {}", first);
}
v.push(6);
{
println!("v = {}", v);
let first = &v[0];
println!("The first element is: {}", first);
}
Which tells me it cannot find 'integer'
impl fmt::Display for Vec<integer>{
^^^^^^^ not found in this scope
cannot find type `integer` in this scope
help: you might be missing a type parameter
<integer>
impl fmt::Display for Vec<integer>{
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use only types from inside the current crate
impl fmt::Display for Vec<integer>{
^^^^^^^^^^^^ `Vec` is not defined in the current crate
only traits defined in the current crate can be implemented for arbitrary types
Isn't integer already imported?
Well, fine. Instead of integer, let's do it generically. But this /also/ fails for
// This doesn't work because first is borrowing an element of v. So I can't modify v after.
use std::fmt;
impl fmt::Display for Vec<T>{
fn fmt(&self) {
for i in self.iter() {
println!("{}", i);
}
}
}
let mut v = vec![1, 2, 3, 4, 5];
{
println!("v = {}", v);
let first = &v[0];
println!("The first element is: {}", first);
}
v.push(6);
{
println!("v = {}", v);
let first = &v[0];
println!("The first element is: {}", first);
}
How does rust print a vector of integers?
Upvotes: 0
Views: 999
Reputation: 16910
The easier way would be to use the debug formatter {:?}
instead of the display formatter {}
.
However, if you really want your custom formatter for a vector, then you cannot do it directly.
In Rust, when you implement a trait for a type, the trait or the type (or both) must come from your crate.
In your attempt, both Display
and Vec
come from std
.
The usual workaround is to use the newtype pattern: you define your own type which just wraps an existing one.
In order to ease the access to the inner type, we can implement Deref
and DerefMut
.
Please find a simple example below.
use std::{
fmt::{Display, Formatter, Result},
ops::{Deref, DerefMut},
};
struct VecProxy<T>(Vec<T>);
impl<T> Deref for VecProxy<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for VecProxy<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: Display> Display for VecProxy<T> {
fn fmt(
&self,
f: &mut Formatter<'_>,
) -> Result {
for i in self.iter() {
writeln!(f, "~~> {}", i)?;
}
Ok(())
}
}
fn main() {
let mut v = VecProxy(vec![1, 2, 3, 4, 5]);
{
println!("v = {}", v);
let first = &v[0];
println!("The first element is: {}", first);
}
v.push(6);
{
println!("v = {}", v);
let first = &v[0];
println!("The first element is: {}", first);
}
}
/*
v = ~~> 1
~~> 2
~~> 3
~~> 4
~~> 5
The first element is: 1
v = ~~> 1
~~> 2
~~> 3
~~> 4
~~> 5
~~> 6
The first element is: 1
*/
Upvotes: 3
Reputation: 60493
You cannot. There are two issues here:
One, there is no {integer}
type in Rust. If you write a integer literal, like 0
, you could mean for it to be one of many different types. It will typically be inferred based on later usage (or sometimes can default to i32
), but until then, and if an error needs to reference a integer type that has not-yet-been deduced, you'll see {integer}
. You may also see {float}
.
Two, you cannot implement implement Display
for Vec
. If you attempt it, the compiler will emit an error like:
error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
--> src/lib.rs:5:1
|
5 | impl Display for Vec<T> {
| ^^^^^^^^^^^^^^^^^------
| | |
| | `Vec` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
This is due to Rust's "orphan rules" that restrict what traits can be implemented for which types to preemptively reject potentially conflicting implementations and aid in trait-lookup.
To print a Vec<_>
with a custom implementation, you'll need to use the newtype idiom that wraps a Vec
and implements Display
on that new type instead:
struct MyFormat(Vec<i32>);
impl Display for MyFormat {
// ...
}
Upvotes: 3