Implementation

Similar to functions, implementations require care to remain generic.

struct S {} // Concrete type `S`

trait T {} // Concrete trait `T`
trait GenericValTrait<T> {} // Generic trait `GenericValTrait`

// impl of GenericVal where we explicitly specify type parameters:
impl GenericValU32 of GenericValTrait<u32> {} // Specify `u32`
impl GenericValS of GenericValTrait<S> {} // Specify `S` as defined above

// `<T>` Must precede the type to remain generic
impl GenericValImpl<T> of GenericValTrait<T> {}
#[derive(Copy, Drop)]
struct Val {
    val: u64,
}

#[derive(Copy, Drop)]
struct GenVal<T> {
    gen_val: T,
}

// impl of Val
trait ValTrait {
    fn value(self: @Val) -> @u64;
}

impl ValImpl of ValTrait {
    fn value(self: @Val) -> @u64 {
        self.val
    }
}

// impl of GenVal for a generic type `T`
trait GenValTrait<T> {
    fn value(self: @GenVal<T>) -> @T;
}

impl GenValImpl<T> of GenValTrait<T> {
    fn value(self: @GenVal<T>) -> @T {
        self.gen_val
    }
}

fn main() {
    let x = Val { val: 3 };
    let y = GenVal { gen_val: 3_u32 };

    println!("{}, {}", x.value(), y.value());
}

See also:

impl, and struct