Generics and Implementations

Assuming Rust literacy I will not explain too much except post a question: How to make this work?

struct Z <T>{
	n: T
}

struct A {
	c: i32
}

struct B {
	c: i64
}

pub trait X {
	fn new()->Self;
}

impl  X  for Z<A> {
	fn new()->Self{
		Z {
		   n: A{c: 8i32}
		}
	}
}

pub trait Y {
	fn new()->Self;
}

impl Y for Z<B> {
	fn new()->Self{
		Z {
		   n: B {c: 8i64}
		}
	}
	
}

fn main() {
    X::new();
    Y::new();
}

I would like to construct two different objects with two different structures inside a generic one called inside each constructor … Any ideas?

Before I begin, your formatting makes your code hard to read, please use rustfmt to format your code. You can use it for snippets on playground in the top right corner under tools.
On the note of playground, can you please share your code via playground next time, it will make it easier for us to help you.


Well, for one you need to specify the type when you call associated functions, even if they are from traits because Rust usually can’t infer that without any hints.

The most minimal change to make this work is,

fn main() {
    let _: Z<_> = X::new();
    let _: Z<_> = Y::new();
}

This gives the compiler enough of a hint to tell what types are involved.


Why do you have two traits with the exact same interface? Traits are abstractions to generalize over a number of types, so it is weird to see that. Also, except for the names of things, this looks just like the Default trait, any special reason for this?


This looks like a toy problem, so I’m not sure what is relevant, can you please post something closer to your actual problem.

1 Like

You can also call the methods on the concrete types. Since for each concrete type there is only a single new() method, the compiler will be able to infer the trait in this case:

fn main() {
    Z::<A>::new();
    Z::<B>::new();
}

Using the fully qualified method call syntax makes it more explicit which method is called:

fn main() {
    <Z<A> as X>::new();
    <Z<B> as Y>::new();
}

In this example, you could replace A and B with _ again, since there is only one possible value for the type parameter in each case, so the compiler can infer it.

2 Likes