Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
991 views
in Technique[技术] by (71.8m points)

rust - Why do I get the error "the trait `Foo` is not implemented for `&mut T`" even though T implements the trait?

I have this source:

pub fn draw<G, C>(&self, font: &mut C, draw_state: &DrawState, transform: Matrix2d, g: &mut G)
where
    C: CharacterCache,
    G: Graphics<Texture = <C as CharacterCache>::Texture>,
{
    self.properties.draw(
        self.text.as_str(),
        &mut font,
        &draw_state,
        transform,
        g,
    );
}

And the error

the trait bound `&mut C: graphics::character::CharacterCache` is not satisfied 
(the trait `graphics::character::CharacterCache` is not implemented for `&mut C`) 

The only aspect of C that is defined is that it implements CharacterCache, yet the error says the opposite.

DrawState, Matrix2d, CharacterCache and its implementations, Texture, and self.properties (Text) are provided by the Piston 2d graphics library. There must be something about traits in general that I'm misunderstanding.

The Text::draw function signature:

fn draw<C, G>(
    &self,
    text: &str,
    cache: &mut C,
    draw_state: &DrawState,
    transform: Matrix2d,
    g: &mut G,
) where
    C: CharacterCache,
    G: Graphics<Texture = C::Texture>,
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

T, &T, and &mut T are all different types; and that means that &mut &mut T is likewise a different type. Traits are not automatically implemented for references to a type. If you wish to implement a trait for either of the references, you need to write it out explicitly.

As an example, this exhibits the same problem:

trait Foo {}

#[derive(Debug, Copy, Clone)]
struct S;
impl Foo for S {}

fn example<T>(_: T)
where
    T: Foo,
{}

fn main() {
    let mut s = S;

    example(s);
    example(&s);     // the trait bound `&S: Foo` is not satisfied
    example(&mut s); // the trait bound `&mut S: Foo` is not satisfied
}

Explicit implementations of the trait for the references solve the problem:

impl<'a> Foo for &'a S {}
impl<'a> Foo for &'a mut S {}

In many cases, you can delegate the function implementations to the non-reference implementation.

If this should always be true, you can make it so by applying it to all references to a type that implements a trait:

impl<'a, T> Foo for &'a T where T: Foo {}
impl<'a, T> Foo for &'a mut T where T: Foo {}

If you don't have control over the traits, you may need to specify that you take a reference to a generic type that implements the trait:

fn example<T>(_: &mut T)
where
    for<'a> &'a mut T: Foo,
{}

See also:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...