【发布时间】:2020-08-21 18:06:07
【问题描述】:
如果我有一个通用泛型类型的“外部”特征(Collection,下面),那么我可以创建一个具有“内部”特征类型(Collection<&dyn Stringable>)的实例。然后我可以在该实例中使用任何值,只要这些值实现嵌套特征 (Stringable):
fn main() {
let mut vs: &mut Collection<&dyn Stringable> = &mut vec![];
vs.add(&1);
vs.add(&true);
vs.add(&3);
for v in vs.get_all() {
println!("{}", v.string());
}
}
trait Collection<T> {
fn add(&mut self, v: T);
fn get_all(&self) -> &Vec<T>;
}
impl<T> Collection<T> for Vec<T> {
fn add(&mut self, v: T) {
self.push(v)
}
fn get_all(&self) -> &Vec<T> {
&self
}
}
trait Stringable {
fn string(&self) -> String;
}
impl Stringable for i8 {
fn string(&self) -> String {
format!("int({})", self)
}
}
impl Stringable for bool {
fn string(&self) -> String {
format!("bool({})", self)
}
}
但是,如果我同时实现了一个类型 (Collection<i8>) 的外部和内部特征,则该类型的值不能放入 Collection<&dyn Stringable> 变量中,即使第一个类型的内部类型 (@ 987654328@) 实现了第二个 (Stringable)。下面的代码给出了以下错误:
the trait `Collection<&dyn Stringable>` is not implemented for `StaticCollection`
代码:
fn main() {
let mut vs: &mut Collection<&dyn Stringable> = &mut StaticCollection{};
for v in vs.get_all() {
println!("{}", v.string());
}
}
struct StaticCollection {}
impl Collection<i8> for StaticCollection {
fn add(&mut self, v: i8) {}
fn get_all(&self) -> &Vec<i8> {
&vec![1, 2, 3]
}
}
是否有可能,例如,写impl Collection<&dyn Stringable> for StaticCollection 之类的东西,以便StaticCollection 可以存储在通用Collection<&dyn Stringable> 变量中?
【问题讨论】:
-
&vec![1, 2, 3]部分无法编译,因为它试图返回对临时对象的引用。我假设你可以解决这个问题,但你会遇到类似的问题,因为Vec<T> is not interchangeable with Vec<dyn U>绑定返回Vec<&dyn Stringable>,你必须创建一个新的 Vec 以将其作为特征对象返回。 -
对于
StaticCollection实现Collection<i8>和Collection<&dyn Stringable>没有一般 问题,只是您选择的接口可能会导致问题。
标签: generics types rust traits