2015-07-10 20 views
4

我想知道是否有可能得到这个编译。使用Formatter :: debug_list来实现一个二维数组的调试

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是产生&[T]的迭代器。

这里的错误是大中未对[T]b.entry(e)的背景下,因为前面提到的迭代器产量&[T]这是奇怪的实现。

我无法弄清楚,部分是因为我无法理解这里涉及的函数签名。

fn entry(self, entry: &Debug) -> DebugList<'a, 'b> 

请注意&Debug

然而,相关文档示例将引用&i32传递给构建器。

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() 
    } 
} 

有了这么多的困惑,必须有一些有趣的东西来学习。

期望的输出将是类似于[[1, 2], [3, 4]]

一个类似的例子,任何人都可以编译:

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() 
} 

回答

5

entry()被这样定义:

pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b>; 

它需要一个fmt::Debug性状对象。因此,当你传递一个&[T]时,它想要将其隐含地转换为&fmt::Debug。但是,这不能完成,因为特征对象只能由大小的对象构成。解决方法是制作大小切片的特征对象;也就是通过&&[T]类型的内容,然后可以隐式转换为&fmt::Debug,其中包含类型&[T]。即,b.entry(&e)而不是b.entry(e)

你的builder线是不必要的,它实际上引入了终生问题;为方便起见,您应将其声明为fold调用的一部分。

这将使你这是您的最终结果:

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() 
    } 
} 
+0

看起来像我的锈是有点生疏。我的印象是,“特质”只能用明确的演员来构建。 –

+0

@ A.B .:您的印象不正确。 –