我试图在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!");
}
臭名昭著的信息是:
编译playground v0.0.1(/playground)错误[E0308]:不匹配的类型-
有关此错误的更多信息,请尝试rustc--explain E0308
。错误:由于以前的错误,无法编译游戏
我不明白为什么编译器抱怨期待Box
< code>dyn I和< code >
T
是在编译时确定的具体类型。dyn I
它是一个“trait对象”,它是动态的,具体类型是未知的,但有点在其中携带。
关于这个主题的一个很好的视频。
转换自
可以使用
Vec修复代码
上述代码导致以下错误: 我的猜测是,问题出在trait中的类属函数。
trait对象在Rust中是指使用指针封装了的 trait,比如 &SomeTrait 和 Box<SomeTrait>。 trait Foo { fn method(&self) -> String; } impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } } impl Foo for String
当涉及到多态的代码时,我们需要一个机制来决定哪个具体的版本应该得到执行。这叫做“分发”(dispatch)。大体上有两种形式的分发:静态分发和动态分发。虽然 Rust 喜欢静态分发,不过它也提供了一个叫做“trait 对象”的机制来支持动态分发。 背景 在本章接下来的内容中,我们需要一个 trait 和一些实现。让我们来创建一个简单的Foo。它有一个返回String的方法。 trait Foo {
问题内容: 在一个我目前正在从事的项目中,我遇到了一个角度异常: 在寻找解决方案的搜索中,我直接在浏览器中输入了Web服务的URL,但令人惊讶的是,我没有收到预期的数组。 Web服务类: 当我输入网址时,我希望看到带有JSON对象的JSON数组: 但是,相反,我收到的JSON对象的属性与我期望的JSON对象相同,没有任何数组: 所以我想知道为什么没有数组,当我添加另一个Clazz对象时会发生什么。