genericsrustinitializationpolymorphismparametric-polymorphism

How to initialize a generic variable in Rust


In a function generic on T, how can I properly create and initialize a variable of type T in safe (or unsafe) Rust? T can be anything. What is the idiomatic way of doing such thing?

fn f<T>() {
    let t: T = todo!("what to put here?");
}

One possible use case might be to use T as a temporary variable for swapping.


Solution

  • Putting a Default bound on T is the idiomatic way to construct generic types within a generic function.

    There's nothing special about the Default trait though and you can declare a similar trait and use that within your generic functions.

    Also, if a type implements Copy or Clone you can initialize as many copies and clones as you want from a single value.

    Commented examples:

    // use Default bound to call default() on generic type
    fn func_default<T: Default>() -> T {
        T::default()
    }
    
    // note: there's nothing special about the Default trait
    // you can implement your own trait identical to it
    // and use it in the same way in generic functions
    trait CustomTrait {
        fn create() -> Self;
    }
    
    impl CustomTrait for String {
        fn create() -> Self {
            String::from("I'm a custom initialized String")
        }
    }
    
    // use CustomTrait bound to call create() on generic type
    fn custom_trait<T: CustomTrait>() -> T {
        T::create()
    }
    
    // can multiply copyable types
    fn copyable<T: Copy>(t: T) -> (T, T) {
        (t, t)
    }
    
    // can also multiply cloneable types
    fn cloneable<T: Clone>(t: T) -> (T, T) {
        (t.clone(), t)
    }
    

    playground