I have a struct Lambertian:
pub struct Lambertian {
albedo: Color,
}
A Material trait with an associated method:
pub trait Material {
fn scatter(&self, ray: &Ray, rec: &HitRecord) -> Option<(Ray, Color)>;
}
And finally, another struct that holds a value of something that implements the Material trait
pub struct HitRecord<T>
where T: Material
{
// snip
pub mat_ptr: Rc<T>,
}
So, I want the generic T in HitRecord to implement Material, but I have a parameter of type HitRecord in the trait method scatter. To make this work, I have to annotate Material with another T, then specifying that that T implements Material as well… Hence doing a recursive definition. What do I need to do instead ?
>Solution :
You can put the generic on the scatter method rather than Material:
pub trait Material {
fn scatter<T>(&self, ray: &Ray, rec: &HitRecord<T>) -> Option<(Ray, Color)>
where
T: Material;
}
Or if you want rec to use the same material type as self, make the generic argument Self:
pub trait Material {
fn scatter(&self, ray: &Ray, rec: &HitRecord<Self>) -> Option<(Ray, Color)>;
}
This requires relaxing the constraint Sized constraint on HitRecord<T>:
pub struct HitRecord<T>
where
T: Material + ?Sized,