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 ?
CodePudding user response:
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,