I have a Hittable
trait, with a method that returns a generic implementing Material
:
pub trait Hittable {
fn hit<T>(&self -> Option<HitRecord<T>>
where T: Material;
}
And an implementation of this trait on a Sphere<T>
:
impl<T> Hittable for Sphere<T>
where T: Material
{
fn hit(&self) -> Option<HitRecord<T>> {
// snip
}
I want the T
in HitRecords
to be the same as the T
in Sphere<T>
, but as of now now it will not compile because I need to annotate the hit
method in the impl with a T as well. But if I do so, the 2 T's will not be forced to be the same. How do I enforce that?
CodePudding user response:
You should uplift the generic parameter from the method into the trait:
pub trait Hittable<T: Material> {
fn hit(&self) -> Option<HitRecord<T>>;
}
impl<T: Material> Hittable<T> for Sphere<T> {
fn hit(&self) -> Option<HitRecord<T>> {
// snip
}
}
Another way is to use an associated type (it models the situation better, but as long as you only implement the trait for one generic parameter it doesn't practically matter):
pub trait Hittable {
type T: Material;
fn hit(&self) -> Option<HitRecord<Self::T>>;
}
impl<T: Material> Hittable for Sphere<T> {
type T = T;
fn hit(&self) -> Option<HitRecord<T>> {
// snip
}
}