我有:
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);
}
}
我想多态地调用trait对象的向量所引用的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
函数。。。
这终于奏效了,谢谢:
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);
}
}
当您编写以下内容时:
write!(f, "{}", *self)
您假设*self
的类型(即Employee
)实现了Display
,这不受类型约束的保证。所以你应该这样做:
trait Employee: fmt::Display {}
作为副作用,它允许您删除impl fmt::Display for Employee
。
由于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);
}
}
如果你想拥有一个不需要实现Display
的Employee
特征(正如Valentin-Lorentz的回答所要求的那样),你可以创建另一个同时需要两者的特征:
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);
}
}