Akshay Takkar
Akshay Takkar

Reputation: 500

"Expected type parameter, found integer" when called from a function but not when called from main

struct Cache<T> {
    key: String,
    val: T
}

impl<T> Cache<T> {
    fn new(k: String, v: T) -> Cache<T> {
        Cache { key: k, val: v }
    }

    fn update(&mut self, v: T) {
        self.val = v;
    }
}

fn increment<T>(cache: &mut Cache<T>, v: T) {
    cache.update(v);
}

fn main() {
    let mut c = Cache::new("akshay".to_string(), 21);
    c.update(25);
    println!("c = {}", c.val);
    increment(&mut c, 30);
    println!("c = {}", c.val);
}

This example works fine. But if I change cache.update(v); to cache.update(25); in the increment function, I get the following error:

cache.update(25);
|            ^^ expected type parameter, found integer
|
= note: expected type `T`
          found type `{integer}`
= help: type parameters must be constrained to match other types

So, my question is why does the cache.update(25) method work from the main function but not from the increment function?

Upvotes: 0

Views: 715

Answers (1)

sshashank124
sshashank124

Reputation: 32189

Because in main, the compiler knows that it's dealing with a Cache with an integer type as the type parameter. However, in the increment function, one could pass in a Cache of any generic type since you are accepting a Cache<T> as a parameter. Thus, if you still tried to call update with an integer argument on a Cache<T>, it would be an issue and therefore the compiler doesn't allow it. Take for example if increment was called with a Cache<String> as an argument, how would cache.update(25) work?

If you wish to only work with Cache<i32> for example, you can restrict your increment function's parameter type:

fn increment(cache: &mut Cache<i32>, v: i32)

otherwise in the generic version of the function, you will have to use just values of type T and cannot do things like cache.update(25)

Upvotes: 2

Related Questions