-1
fn foo<T>() -> f32 {
    return 0.0;
}

So I want to define a function that accepts only certain types (e.g. i32, i64, f32) as template parameter.

For this case I hope to define only foo<i32>(), foo<i64>(), foo<f32>() and nothing more.

How do I achieve so?

Rahn
  • 4,787
  • 4
  • 31
  • 57
  • 5
    Don't know the complexity of your function, but you could create a marker trait (empty trait) and implement it only for the types you want in your interface. Then use `foo` in your signature. – Jonas Fassbender Jun 15 '23 at 12:42
  • 3
    "How do I achieve so?" You don't, that's not how Rust works. In Rust, generic *functions* work in terms of trait bounds, and you don't get to peek through the trait to get the concrete type. As to what your options are, it would be much easier if you explained what you're actually trying to achieve rather than how. But you might want to look at the `Default` trait, squinting a bit your `foo` doesn't look entirely dissimilar. num's `Zero` trait as well. – Masklinn Jun 15 '23 at 12:51
  • 3
    Maybe what you actually want is a trait with an associated function, rather than a generic function? – Sven Marnach Jun 15 '23 at 12:56
  • Do you want also for the generic function to have a return type ? – kumarmo2 Jun 15 '23 at 13:27

1 Answers1

0

You would define a trait. Traits are the paradigm through which rust creates type-dependent behavior.

pub trait Foo {
    fn foo() -> f32;
}

Then you can implement it for the types you want.

impl Foo for i32 {
    fn foo() -> f32 {
        1.0
    }
}

impl Foo for i64 {
    fn foo() -> f32 {
        2.0
    }
}

impl Foo for f32 {
    fn foo() -> f32 {
        3.0
    }
}

And now you can call it using your specific types.

i32::foo() // 1.0

You can also use the trait to create type-specific behavior in other functions.

pub fn foo_plus_one<T: Foo>() -> f32 {
    T::foo() + 1.0
}

foo_plus_one::<i64>() // 3.0
drewtato
  • 6,783
  • 1
  • 12
  • 17