What is the difference between impl<T> and impl<T: Config>

I am trying to understand some basics of the language by reading some tutorial where a function is implemented for a structure as follows:

pub struct Kitty<Hash, Balance> {
id: Hash,
dna: Hash,
price: Balance,
gender: Gender,
}

impl<T: Config> Kitty<T, T> {
pub fn gender(dna: T::Hash) -> Gender {
if dna.as_ref()[0] % 2 == 0 {
Gender::Male
} else {
Gender::Female
}
}
}

I do not understant why impl<T: Config> is used instead of just impl
Also, why use T twice here: Kitty<T, T> ?

You put a trait bound on a type variable when you need to rely on the guarantees provided by that bound. In this case, the T::Hash associated type is used in the signature, so I suspect that might be provided by the Config trait.

Because the type Kitty has two type parameters, you have to supply two type parameters to use it. They may be the same type, there's nothing wrong with that in itself.

1 Like
pub struct Kitty<Hash, Balance> {
    id: Hash,
    dna: Hash,
    price: Balance,
    gender: Gender,
}

Here, the struct takes two type parameters, Hash and Balance. You could have a Kitty<String, u32> for example, in which id and dna would be Strings and price would be a u32. gender, in contrast, is always a field with type Gender.

impl<T: Config> Kitty<T, T> { /* ... */ }

They say Kitty<T, T> here because they needed to specify both type parameters and make sure they were the same. (If they always had to be the same, Kitty would only have one type parameter.)

Also, T: Config is saying "use this implementation for any type T that implements Config". Config is a trait. Because of this trait bound, they can make use of the Config trait properties on T inside the implementation. For example here:

 pub fn gender(dna: T::Hash) -> Gender { /* ... */ }

We can see that the Config type must have an associated type called Hash. (Note that, just like function parameters names need not be related to the variables you call them with, this associated type need not be related to the type parameter on Kitty.)

If they didn't have the bound, they wouldn't be able to use T::Hash, or any other properties of the Config trait; the bound is checked at compile time.


P.s. Welcome to URLO! Please see the pinned formatting post. :slight_smile:

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.