预期特征对象“dyn Responsability”,找到类型参数“T”
expected trait object `dyn Responsability`, found type parameter `T`
我正在尝试在 Rust 中实现责任链:
use std::error::Error;
struct Query {
query: String,
}
struct Response {
response: u64,
}
trait Responsability {
fn take(&self, iterator: std::slice::Iter<Box<dyn Responsability>>, query: Query) -> Result<Response, Box<dyn Error>>;
}
struct ResponsabilityChain<T: Responsability> {
responsabilities: Vec<Box<T>>,
}
impl<T: Responsability> ResponsabilityChain<T>
where
T: Responsability,
{
pub fn new(responsabilities: Vec<T>) -> Self {
let responsabilities = responsabilities.into_iter()
.map(|elt| Box::new(elt))
.collect();
Self { responsabilities }
}
pub fn launch(&self, query: Query) -> Result<Response, Box<dyn Error>> {
let iterator = self.responsabilities.iter();
let responsability = iterator.next().unwrap();
responsability.take(iterator, query)
}
}
fn main() {
println!("Hello, world!");
}
臭名昭著的消息是:
Compiling playground v0.0.1 (/playground) error[E0308]: mismatched
types --> src/main.rs:35:29 | 19 | impl<T: Responsability>
ResponsabilityChain | - this type parameter ... 35 |
responsability.take(iterator, query) |
^^^^^^^^ expected trait object dyn Responsability
, found type
parameter T
| = note: expected struct std::slice::Iter<'_, Box<(dyn Responsability + 'static)>>
found struct std::slice::Iter<'_, Box<T>>
= help: type parameters must be constrained to match other types = note:
for more information, visit
https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
For more information about this error, try rustc --explain E0308
.
error: could not compile playground
due to previous error
我不明白为什么编译器抱怨期望 Box<dyn Responsability>
而有 Box<T>
因为我指定 T: Responsability
。我做错了什么?
dyn I
和 <T> where T: I
在 Rust 中是不同的类型,因此编译器会报错,因为没有隐式转换。
T
是在编译时确定的具体类型。 dyn I
它是一个“特征对象”,它是动态的,具体类型未知,但有点包含在其中。
A good video on the topic.
从 <T> where T: I
到 dyn I
的转换不是免费的,它有运行时成本,因此必须明确 Rust 的哲学。
代码可以通过在所有地方使用 Vec<Box<dyn Responsability>>
来修复。它还将允许您将任意类型传递给 new()
,这可能是您想要的,因为 Vec<T>
必须包含相同类型的对象(请记住,此类型是在编译时确定的)。
我正在尝试在 Rust 中实现责任链:
use std::error::Error;
struct Query {
query: String,
}
struct Response {
response: u64,
}
trait Responsability {
fn take(&self, iterator: std::slice::Iter<Box<dyn Responsability>>, query: Query) -> Result<Response, Box<dyn Error>>;
}
struct ResponsabilityChain<T: Responsability> {
responsabilities: Vec<Box<T>>,
}
impl<T: Responsability> ResponsabilityChain<T>
where
T: Responsability,
{
pub fn new(responsabilities: Vec<T>) -> Self {
let responsabilities = responsabilities.into_iter()
.map(|elt| Box::new(elt))
.collect();
Self { responsabilities }
}
pub fn launch(&self, query: Query) -> Result<Response, Box<dyn Error>> {
let iterator = self.responsabilities.iter();
let responsability = iterator.next().unwrap();
responsability.take(iterator, query)
}
}
fn main() {
println!("Hello, world!");
}
臭名昭著的消息是:
Compiling playground v0.0.1 (/playground) error[E0308]: mismatched types --> src/main.rs:35:29 | 19 | impl<T: Responsability> ResponsabilityChain | - this type parameter ... 35 |
responsability.take(iterator, query) |
^^^^^^^^ expected trait objectdyn Responsability
, found type parameterT
| = note: expected structstd::slice::Iter<'_, Box<(dyn Responsability + 'static)>>
found structstd::slice::Iter<'_, Box<T>>
= help: type parameters must be constrained to match other types = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parametersFor more information about this error, try
rustc --explain E0308
. error: could not compileplayground
due to previous error
我不明白为什么编译器抱怨期望 Box<dyn Responsability>
而有 Box<T>
因为我指定 T: Responsability
。我做错了什么?
dyn I
和 <T> where T: I
在 Rust 中是不同的类型,因此编译器会报错,因为没有隐式转换。
T
是在编译时确定的具体类型。 dyn I
它是一个“特征对象”,它是动态的,具体类型未知,但有点包含在其中。
A good video on the topic.
从 <T> where T: I
到 dyn I
的转换不是免费的,它有运行时成本,因此必须明确 Rust 的哲学。
代码可以通过在所有地方使用 Vec<Box<dyn Responsability>>
来修复。它还将允许您将任意类型传递给 new()
,这可能是您想要的,因为 Vec<T>
必须包含相同类型的对象(请记住,此类型是在编译时确定的)。