I am reading the book "Rust for Rustaceans" and on page 33 J. Gjengset gives an example for a excessively generic implementation of Debug for any iterable collection
:
impl Debug for AnyIterable
where for<'a> &'a Self: IntoIterator,
where for<'a> &'a Self as IntoIterator>::Item: Debug {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
// The bounds are needed for `entries(...)`.
f. debug_list().entires(self).finish()
}
}
I tried to implement this to try it out and I stumbled across the following questions which
are unclear to me.
IntoIterable
should be meant for constructing a consuming iterator. But you can implement it on
on value types (truely consuming) or reference types (which would then just be the same asiter()
).
So I came up with this example:
#![feature(impl_trait_in_assoc_type)]
use std::{fmt::Debug, iter::Flatten, sync::Arc};
struct Store {
a: Vec<i32>,
}
impl<'a> IntoIterator for &'a Store {
type Item = &'a i32;
type IntoIter = impl Iterator<Item = Self::Item>;
fn into>_iter(self) -> Self::IntoIter {
println!("refimpl");
(&self.a).into_iter()
}
}
impl IntoIterator for Store {
type Item = i32;
type IntoIter = impl Iterator<Item = Self::Item>;
fn into_iter(self) -> Self::IntoIter {
println!("valueimpl");
self.a.into_iter()
}
}
impl Debug for Store
where
Self: IntoIterator,
<Self as IntoIterator>::Item: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(self).finish()
}
}
fn main() {
let i = Store { a: vec![1, 3, 4] };
for v in &i {
println!("{:?}", v);
}
for v in i {
println!("{:?}", v);
}
}
As I see I dont even need the higher-ranked trait bound. Whats the difference between
the one J. Gjengset proposes and the one I coded, they work the same or is there some culprit?