如何使我自己的适配器方法能够使用特征对象?
How do I make my own adapter methods able to consume a trait object?
我有一个 "adapter methods" 使用方法的特征:
struct Bar<T>(T);
trait Foo {
fn make_bar(self) -> Bar<Self>
where
Self: Sized,
{
Bar(self)
}
}
impl Foo for u8 {}
impl Foo for bool {}
这是仿照 Iterator
设计的。当我使用 Box<Iterator>
时,我仍然可以调用 Iterator
适配器方法,例如 map
或 filter
:
fn main() {
let a = vec![1, 2, 3];
let b: Box<Iterator<Item = u8>> = Box::new(a.into_iter());
let c = b.map(|x| x * 2);
for z in c {
println!("{}", z)
}
}
但是,我定义的方法的工作方式不同:
fn main() {
let a: Box<Foo> = Box::new(42);
a.make_bar();
}
失败并出现错误
error[E0277]: the trait bound `Foo: std::marker::Sized` is not satisfied
--> src/main.rs:18:7
|
18 | a.make_bar();
| ^^^^^^^^ `Foo` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `Foo`
Foo
没有尺码是绝对正确的 - 这是一个特征。但是,据我了解,Box<Foo>
应该 有大小。 Iterator
与我的代码有何不同?
因为 Iterator
是对象安全的,特征对象 Iterator
实现 Iterator
.
因为impl<I: Iterator + ?Sized> Iterator for Box<I>
,装箱特征对象Box<Iterator>
实现了Iterator
.
因此,在您的情况下,解决方案是为 Box<Foo>
实施 Foo
。这可以是通用的,例如 Iterator
(impl<T: ?Sized + Foo> Foo for Box<T> { }
),也可以是特定的 (impl Foo for Box<Foo> { }
)。
我有一个 "adapter methods" 使用方法的特征:
struct Bar<T>(T);
trait Foo {
fn make_bar(self) -> Bar<Self>
where
Self: Sized,
{
Bar(self)
}
}
impl Foo for u8 {}
impl Foo for bool {}
这是仿照 Iterator
设计的。当我使用 Box<Iterator>
时,我仍然可以调用 Iterator
适配器方法,例如 map
或 filter
:
fn main() {
let a = vec![1, 2, 3];
let b: Box<Iterator<Item = u8>> = Box::new(a.into_iter());
let c = b.map(|x| x * 2);
for z in c {
println!("{}", z)
}
}
但是,我定义的方法的工作方式不同:
fn main() {
let a: Box<Foo> = Box::new(42);
a.make_bar();
}
失败并出现错误
error[E0277]: the trait bound `Foo: std::marker::Sized` is not satisfied
--> src/main.rs:18:7
|
18 | a.make_bar();
| ^^^^^^^^ `Foo` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `Foo`
Foo
没有尺码是绝对正确的 - 这是一个特征。但是,据我了解,Box<Foo>
应该 有大小。 Iterator
与我的代码有何不同?
因为 Iterator
是对象安全的,特征对象 Iterator
实现 Iterator
.
因为impl<I: Iterator + ?Sized> Iterator for Box<I>
,装箱特征对象Box<Iterator>
实现了Iterator
.
因此,在您的情况下,解决方案是为 Box<Foo>
实施 Foo
。这可以是通用的,例如 Iterator
(impl<T: ?Sized + Foo> Foo for Box<T> { }
),也可以是特定的 (impl Foo for Box<Foo> { }
)。