NutellaFan
NutellaFan

Reputation: 85

Embedding a Rust generic with generic functions inside another struct

I have this generic type:

pub struct MyContainer<T, S> {
    array: Vec<T>,
    get_size: S,
    size: u32,
}

impl<T: Default, S> MyContainer<T, S>
where
    S: Fn(&T) -> u32,
{
    pub fn new(size: u32, get_size: S) -> MyContainer<T, S> {
        let array = Vec::with_capacity(size as usize);
        MyContainer {
            array,
            get_size,
            size,
        }
    }
}

I can easily create a container using compiler deduction magic:

pub fn get_size_func(h: &House) -> u32 {
    h.num_rooms
}
let container = MyContainer::new(6, get_size);

However, I'm hitting an issue when I try to instantiate my generic type in another struct:

pub struct City {
    suburbs: MyContainer<House, fn(&House) -> u32>,
}

impl City {
    pub fn new(num_houses: u32) -> City {
        let container = MyContainer::new(num_houses, get_size_func);
        City { suburbs: container }
    }
}

I get

error[E0308]: mismatched types
  --> src/lib.rs:44:25
   |
44 |         City { suburbs: container }
   |                         ^^^^^^^^^ expected fn pointer, found fn item
   |
   = note: expected type `MyContainer<_, for<'r> fn(&'r House) -> u32>`
              found type `MyContainer<_, for<'r> fn(&'r House) -> u32 {get_size_func}>`

Here's the Rust playground that reproduces the problem

Upvotes: 1

Views: 554

Answers (1)

NutellaFan
NutellaFan

Reputation: 85

There's two answers to this question:

  1. Specifying the type parameters when creating the the container. I don't know why that works, but it does:

    let container = MyContainer::<House, fn(&House) -> u32>::new(num_houses, get_size_func);
    
  2. You can also define a generic function that calls a generic trait for an added kick. For example:

     let container = MyContainer::<House, fn(&House) -> u32>::new(num_houses, get_size_func2::<House>);
    

    get_size_func2 would be a trait bound generic function.

Here's the full playground. For both solutions, type parameters are required and not deduced in the City::new function.

Upvotes: 1

Related Questions