我有以下代码(属于较大库的一部分)。编译器告诉我,一个元组没有实现特征,但是我既有一个元组的实现,又有该元组的一个元素的实现。它可以与另一种元组一起使用。
为什么元组(BTreeSet<Annotation>)
在这里不匹配?
use std::collections::BTreeSet;
pub struct Axiom {}
pub struct Annotation {}
pub struct AnnotatedAxiom {
pub axiom: Axiom,
pub annotation: BTreeSet<Annotation>,
}
trait Render {
/// Render a entity to Write
fn render(&self);
}
impl<'a, T: Render> Render for &'a BTreeSet<T> {
fn render(&self) {}
}
impl<'a, A: Render> Render for (&'a A,) {
fn render(&self) {
(&self.0).render();
}
}
/// The types in `Render` are too long to type.
macro_rules! render {
($type:ty, $self:ident,
$body:tt) => {
impl Render for $type {
fn render(& $self)
$body
}
}
}
render!{
Annotation, self,
{
}
}
render!{
Axiom, self,
{
}
}
render!{
AnnotatedAxiom, self,
{
// Axiom implements Render
(&self.axiom).render();
// Annotation implements Render
(&self.annotation).render();
// A 1-element tuple of Axiom implements Render
(&self.axiom,).render();
// A 1-element tuple of Annotation does!?
(&self.annotation,).render();
}
}
fn main() {}
error[E0599]: no method named `render` found for type `(&std::collections::BTreeSet<Annotation>,)` in the current scope
--> src/main.rs:62:29
|
62 | (&self.annotation,).render();
| ^^^^^^
|
= note: the method `render` exists but the following trait bounds were not satisfied:
`(&std::collections::BTreeSet<Annotation>,) : Render`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `render`, perhaps you need to implement it:
candidate #1: `Render`
答案 0 :(得分:3)
实施链中存在空白:
impl<'a, T: Render> Render for &'a BTreeSet<T> {
// ....
}
impl<'a, A: Render> Render for (&'a A,) {
// ...
}
第一个impl
为Render
提供引用的BTreeSet
,而第二个{<1>}提供了 reference元组的实现 Render
。由于BTreeSet
本身未实现Render
(仅对其进行引用!),因此编译器将拒绝工作。
在这种情况下,从引用中抽象出来更符合人体工程学,因为Render
似乎适合于对另一个Render
可能值的任何引用。对所有引用&T
实施此特征,其中T: Render
:
impl<'a, T> Render for &'a T
where
T: Render,
{
fn render(&self) {
(**self).render();
}
}
由于以下原因,其余实现变得稍微简单了:
impl<T> Render for BTreeSet<T>
where
T: Render,
{
fn render(&self) {}
}
impl<A> Render for (A,)
where
A: Render,
{
fn render(&self) {
(&self.0).render();
}
}
另请参阅: