2015-07-10 19 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 .:您的印象不正確。 –