A question about Associated types

I am learning rust by examples , I see a example about Associated types

I want to make some modifications but an error from compiler.

Blockquote
trait Contains {
type A;
type B;
fn contain(&self,:&Self::A,:&Self::B)->bool;
fn first(&self) -> i32;
fn second(&self) -> i32;
}
struct container(i32, i32);

impl Contains for container {
type A =i32;
type B =i32;
fn contain(&self,a:&i32,b:&i32)->bool {
&self.0 == a && &self.1 == b
}
fn first(&self) -> i32{
self.0
}
fn second(&self) -> i32 {
self.1
}
}
fn diff<C:Contains>(c:&C)->i32 {
//c.contain(&A,&B); how can I make this line uncomment and compile?
c.first() -c.second()
}

A and B are types, not values. What are you actually trying to do?


As an aside, please format your code by putting it between three backticks, like this:

```
code
```

sorry for my code format ,it is my first time use this editor.
I just want to call c.contain in diff function

See this pinned post. You can click the pencil to edit your previous posts.

The way you have defined the trait, there's no way to get a Contains::A or Contains::B returned from the implementing type; the only thing you use the associated types are taking arguments of diff. So any code utilizing the trait is going to have to (1) know what those associated types are and (2) supply their own values in order to use the diff method. For example:

fn diff<C: Contains<A=i32, B=i32>>(c: &C) -> i32 {
//                 ^^^^^^^^^^^^^^ Specify what they are
    c.contain(&20, &30);
//            ^^^^^^^^ So I can supply the values myself
    c.first() - c.second()
}

That compiles, but doesn't seem terribly useful. It seems that you're thinking the associated types of traits are a mechanism for specifying some fields that the implementing types must have, which can then be somehow accessed. That's not what associated types are[0] -- the concept of "fields in traits" may some day be pursued in Rust, but doesn't exist today.

[0]: You can emulate this using associated types, getters, and setters. But it will still be odd to use some getters to get some values out of a type and then immediately turn around and pass those back to a method on the type. Instead you would just have a method on the type that utilizes it's own fields internally.

Associated types are like generic type parameters in some ways, but there are important differences. I like to think of it in terms of implementations: You can have a separate implementation for each (trait + generic type parameter combination), but specifying associated types is something you do as part of an implementation (just like defining associated functions). This means, for example, you can't have two implementations of the same (trait + type parameters) that have different associated types. Here's an example of what I mean comparing Deref to AsRef<T>, and also looking at Add<T>.

There's some more discussion in the RFC. (Note that it's a pre-1.0 RFC and it resulted in changing a lot of things to use associated types, etc, so there are some examples that don't match what is in Rust/the standard library today.) The aspect I covered in my example are in this section, wherein type parameters are deemed inputs and associated types are outputs.