2016-05-15 31 views
0

我:如何在其多態類型上調用Display特性?

use std::fmt; 
struct TeamMember { 
    name: String, 
    age: u32, 
} 

struct Manager { 
    name: String, 
    age: u32, 
} 

impl fmt::Display for TeamMember { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "TeamMember; name => {}, age => {}", self.name, self.age) 
     } 
} 

impl fmt::Display for Manager { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "Manager; name => {}, age => {}", self.name, self.age) 
     } 
} 

trait Employee {} 

impl fmt::Display for Employee { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "{}", *self) 
     } 
} 

fn main() { 
    let t = TeamMember { name: "abc".to_string(), age: 23 }; 
    let t2 = Manager { name: "xyz".to_string(), age: 18 }; 

    let mut v: Vec<&Employee> = Vec::new(); 
    v.push(&t); 
    v.push(&t2); 

    for it in &v { 
     println!("i am a {}", *it); 
    } 
} 

我想多態調用2種具體類型特徵的矢量對象引用的顯示器。我得到以下編譯錯誤:

<std macros>:2:21: 2:52 error: the trait `core::marker::Sized` is not implemented for the type `Employee` [E0277] 
<std macros>:2 $ dst . write_fmt (format_args ! ($ ($ arg) *))) 
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
<std macros>:2:21: 2:52 note: in this expansion of format_args! 

矢量迭代應該呼籲的具體類型Display功能...

回答

0

當你這樣寫:

write!(f, "{}", *self) 

你承擔的類型*self(即Employee)實現了Display,這不受類型約束的保證。所以,你應該做的:

trait Employee: fmt::Display {} 

其中,作爲一個副作用,讓您免去您的impl fmt::Display for Employee

+0

我試過了你說的,即從fmt:Display中刪除了impl fmt :: Display for employee和extended Employee,但是沒有工作。 – ddastoor

+0

現在我得到了=> rustc /home/dastoor/rust_examples/polymorphic_display_trait.rs /home/dastoor/rust_examples/polymorphic_display_trait.rs:40:12:40:14錯誤:特徵'Employee'沒有爲' TeamMember' [E0277] /home/dastoor/rust_examples/polymorphic_display_trait.rs:40 v.push(&t); – ddastoor

+0

這些都是另一個問題,而且錯誤信息對於你需要做的事情很明確 –

1

這最後的工作,感謝:

use std::fmt; 

struct TeamMember { 
    name: String, 
    age: u32, 
} 
struct Manager { 
    name: String, 
    age: u32, 
} 

impl fmt::Display for TeamMember { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "TeamMember!; name => {}, age => {}", self.name, self.age) 
    } 
} 

impl fmt::Display for Manager { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "Manager!; name => {}, age => {}", self.name, self.age) 
    } 
} 

trait Employee: fmt::Display {} 
impl Employee for TeamMember {} 
impl Employee for Manager {} 

fn main() { 
    let t = TeamMember { 
     name: "abc".to_string(), 
     age: 23, 
    }; 
    let t2 = Manager { 
     name: "xyz".to_string(), 
     age: 18, 
    }; 

    let mut v: Vec<&Employee> = Vec::new(); 
    v.push(&t); 
    v.push(&t2); 

    for it in &v { 
     println!("i am a {}", *it); 
    } 
} 
+0

你應該接受這個答案 –

0

由於Employee沒有方法,沒有必要創建另一個特點。你可以只用Display直接:

use std::fmt::Display; 

fn main() { 
    let t = TeamMember { name: "abc".to_string(), age: 23 }; 
    let t2 = Manager { name: "xyz".to_string(), age: 18 }; 

    let v = vec![&t as &Display, &t2]; 
    for it in &v { 
     println!("i am a {}", *it); 
    } 
} 

如果你想有一個Employee特點是沒有要求Display中實現(如在Valentin Lorentz' answer是必需的),你可以創建一個既需要另一個特點:

use std::fmt::Display; 

trait Employee {} 
impl Employee for TeamMember {} 
impl Employee for Manager {} 

trait PrintableEmployee: Employee + Display {} 
impl<T> PrintableEmployee for T where T: Employee + Display {} 

fn main() { 
    let t = TeamMember { name: "abc".to_string(), age: 23 }; 
    let t2 = Manager { name: "xyz".to_string(), age: 18 }; 

    let v = vec![&t as &PrintableEmployee, &t2]; 

    for it in &v { 
     println!("i am a {}", *it); 
    } 
} 
+0

非常有趣...謝謝..當然,如果員工在其中有其他funcs,但我想利用std :: Display trait(沒有定義特效中的新func),那麼我想,那將是要走的路,對吧? – ddastoor

+0

@ddastoor更新與例子。 – Shepmaster