Reputation: 16660
I'm wondering if it's possible to get this to compile.
impl<T: fmt::Debug> fmt::Debug for Array2<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let ref mut builder = f.debug_list();
self.rows().fold(builder, |b, e| b.entry(e)).finish()
}
}
self.rows
is an iterator that yields &[T]
.
The error here is that Sized is not implement for [T]
in the context of b.entry(e)
, which is bizarre because the iterator yields &[T]
as mentioned before.
I'm not able to figure this out, in part because I can't make sense of the function signatures involved here.
fn entry(self, entry: &Debug) -> DebugList<'a, 'b>
Note the &Debug
.
Yet the relevant documentation example is passing references &i32
to the builder.
struct Foo(Vec<i32>);
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.0.iter().fold(fmt.debug_list(), |b, e| b.entry(e)).finish()
}
}
With this much confusion there has to be something interesting to learn.
The desired output would be something like [[1, 2], [3, 4]]
.
A similar example that anyone can compile:
use std::fmt;
fn fmt<T: fmt::Debug>(vec: &Vec<T>, f: &mut fmt::Formatter) -> fmt::Result {
let ref mut builder = f.debug_list();
vec.chunks(4).fold(builder, |b, e| b.entry(e)).finish()
}
Upvotes: 4
Views: 345
Reputation: 90832
entry()
is defined thus:
pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b>;
It takes a fmt::Debug
trait object. Thus when you pass it a &[T]
, it wants to cast it implicitly to &fmt::Debug
. This, however, cannot be done, for trait objects can only be constructed of sized objects. The solution is to make a trait object of the sized slice; that is, pass something of type &&[T]
which can then be implicitly converted to &fmt::Debug
, containing the type &[T]
. That is, b.entry(&e)
instead of b.entry(e)
.
Your builder
line is unnecessary too and actually introduces lifetime problems; you should declare it as part of the fold
call for convenience.
This leaves you with this as your final result:
impl<T: fmt::Debug> fmt::Debug for Array2<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.rows().fold(&mut f.debug_list(), |b, e| b.entry(&e)).finish()
}
}
Upvotes: 5