ChosunOne
ChosunOne

Reputation: 734

Is it possible to create a type alias in a struct in Rust?

I am working with some generic structs like the following:

pub struct Example<A, B, C, D, E, F> {
    inner: OtherExample<A, B, C, D, E, F>
    ...
}

and throughout implementing methods of this struct, I have to keep referring to that huge set of types like so:

impl<A, B, C, D, E, F> Example<A, B, C, D, E, F> {
    pub fn get_inner(&self) -> &OtherExample<A, B, C, D, E, F> { 
        &self.inner
    }
    ...
}

and I'm wondering if there is a way to shorten up the notation on all these generic types. For the sake of readability, I can't just use single letters like I have in the examples above, so I would really want to create a generic type alias in the struct like so:

pub struct Example<AliasedGenerics = <A, B, C, D, E, F>> {
    inner: OtherExample<AliasedGenerics>
    ...
}

impl<AliasedGenerics = <A, B, C, D, E, F>> Example<AliasedGenerics> {
    pub fn get_inner(&self) -> &OtherExample<AliasedGenerics> {
        &self.inner
    }
    ...
}

So that I don't have to keep writing extremely long lines and improve the readability of the generic implementation.

Upvotes: 8

Views: 4893

Answers (1)

Caesar
Caesar

Reputation: 8484

Without knowing more context, I can't say whether this will solve your problem, but you can use associated types to do something rather similar:

// Define the "alias"
pub trait GenericsSet { type A; type B; type C; }

pub struct Example<G: GenericsSet>(OtherExample<G>);
pub struct OtherExample<G: GenericsSet> { a: G::A, b: G::B, c: G::C, }

// I was a bit surprised that it is possible,
// but it seems you can even impose limits on some of the parameters
impl<G: GenericsSet<C = String>> Example<G> {
    fn foo(&self) -> &str { &self.0.c }
    fn get_inner(&self) -> &OtherExample<G> { &self.0 }
}

// Here, the illusion fades a bit: 
// You'll need a type for each combination of types you want to use
struct MyGS1 {}
impl GenericsSet for MyGS1 { type A = (); type B = bool; type C = String; }

fn main() {
    println!("{}", Example::<MyGS1>(OtherExample {a: (), b: true, c: "works".into() }).foo())
}

Playground

I would recommend against using this trick in a public API, though.

Upvotes: 10

Related Questions