2015-11-17 48 views
1

學習語言它已經令我感到詫異,我不能輸出的Vec<>一個實例:Vec <T>爲什麼不實現Display特性?

main.rs:8:26: 8:28 error: the trait `core::fmt::Display` is not implemented for the type `collections::vec::Vec<_>` [E0277] 
main.rs:8  println!("{}", v1); 

我能理解這一點,我知道使用{:?}調試佔位符描述here的。不幸的是,我還不明白答案,即爲什麼我不能這樣做。對於C#或Haskell來說這將是非常簡單的任務,不是嗎?對於可序列化(或可轉換爲String)的任何T,我將執行Display特性Vec<T>。對於我爲什麼不能這樣做,我可以有不同的解釋嗎?它是類型系統的限制嗎?

+2

你見過http://stackoverflow.com/questions/30633177/implement-fmtdisplay-for-vect?這個問題也問爲什麼你不能實現'顯示'Vec ' –

+0

謝謝!不過,我不明白。爲什麼我需要額外的東西像'struct'來實現特性? – UserControl

+1

因爲如果可以的話,別人也可以,然後你會有兩個實現,編譯器永遠不會知道哪一個要調用 –

回答

9

首先,你不能實現一個外國類型的外國特質,這就是問題的答案,並提供了ker提供的link

原則上,沒有任何東西可以阻止在模塊中實施DisplayVec,其中任何一個模塊都已定義(最有可能在collections::vec)。但是,這是故意沒有完成的。正如在thisthis RFC中所解釋的那樣,Display特性旨在產生應顯示給用戶的字符串。但是,從矢量生成這樣的字符串沒有自然的方法。你想要逗號分隔的項目或製表符分隔的項目?它們是否應該用括號或大括號包裹或不包含任何東西?也許你想打印每個元素在其單獨的行?沒有一個單一的方式。

解決此問題的最簡單方法是使用新類型包裝器。例如:

use std::fmt; 

struct SliceDisplay<'a, T: 'a>(&'a [T]); 

impl<'a, T: fmt::Display+'a> fmt::Display for SliceDisplay<'a, T> { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     let mut first = true; 
     for item in self.0 { 
      try! { 
       if !first { write!(f, ", {}", item) } 
       else { write!(f, "{}", item) } 
      } 
      first = false; 
     } 
     Ok(()) 
    } 
} 

let items = vec![1, 2, 3, 4]; 
println!("{}", SliceDisplay(&items)); 
相關問題