Axel
Axel

Reputation: 5111

How to pass default generic type in rust function?

So I have a function called cr where I want the generic T to be serde_json::Value by default. How can I do this?

fn main() {
    cr()
}

fn cr<T = serde_json::Value>() {

}

I get this error: cannot infer type for type parameter T declared on the function cr while calling cr. And on cr function I get this error: defaults for type parameters are only allowed in struct, enum, type, or trait definitions.

Upvotes: 5

Views: 7671

Answers (2)

Sunding Wei
Sunding Wei

Reputation: 2214

Here is the trick

type Echo<X = i32> = std::result::Result<X, String>;

fn test(x: Echo) {
    // ...
}

fn main() {
    test(Err("test".into()));
}

Upvotes: -2

Dawer
Dawer

Reputation: 349

As the error said you cannot use default type parameters in function signatures. You can workaround this with a wrapper type.

use std::marker::PhantomData;

struct MyDefault;
struct Custom;

pub fn main() {
    Wrapper::cr(); //~ ERROR type annotations needed
    <Wrapper>::cr();

    Wrapper::<Custom>::cr();
    <Wrapper<Custom>>::cr();
}

struct Wrapper<T = MyDefault>(PhantomData<T>);

impl<T> Wrapper<T> {
    fn cr() {
        let _: T = todo!();
    }
}

Inference cannot guess so it needs a type hint that can be used for substitution. For example let x: SomeType<SubstType> or fully qualified path <SomeType<SubstType>>::associated_item. Omitting the substitutions here triggers the default substitution in SomeType.

Upvotes: 3

Related Questions