我有:
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 :(得分:2)
这终于奏效了,谢谢:
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);
}
}
答案 1 :(得分:0)
当你这样写:
write!(f, "{}", *self)
您假设*self
(即Employee
)的类型实现了Display
,这不受类型约束的保证。所以你应该这样做:
trait Employee: fmt::Display {}
作为副作用,您可以删除impl fmt::Display for Employee
。
答案 2 :(得分: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);
}
}