Rust also supports it, and it's actually very commonly used. For example, the function `Default::default()`, where Default is a trait that you can easily implement for your own types, too.
I am a bit confused here, are you talking about something that would require templates in C++?
template <T>
auto func(T t) { return t; }
y = func<int>(5);Here is the gist of it. Inferring types in C++ (and languages with type deduction) basically looks like this:
auto a = something;
Here, the type of a is determined by the type of something. The left hand side determines the type of the right hand side.In Rust (and languages with type inference), inferring types can look like that:
let a = something;
but it can also "go backwards": let a = 5;
let b: u64 = a;
Here, a will be a u64, because you later assign it to something of type u64, and so the compiler can "work backwards" to infer this. (In my understanding, it does not literally work backwards, but it feels like it.)To see how this plays out in your parent's comment, I adapted the code from: https://docs.microsoft.com/en-us/cpp/cpp/auto-cpp?view=vs-20...
#include<vector>
void func(std::vector<int> &vect)
{
vect.push_back(30);
}
int main()
{
std::vector<int> vect;
vect.push_back(10);
vect.push_back(20);
func(vect);
return 0;
}
You can't say "auto vect;" there, or else gcc will say "error: declaration of 'auto vect' has no initializer".But in Rust, you can write:
fn func(vect: &mut Vec<i32>) {
vect.push(30);
}
fn main() {
let mut vect = Vec::new();
vect.push(10);
vect.push(20);
func(&mut vect);
}
no type annotation on "let mut vect" there; it can see that you eventually pass it to func, and that's enough to infer the type. (For completeness, the line would be "let mut vect: Vec<i32> = Vec::new();" if you wrote out the type. use std::collections::HashMap;
fn main() {
let mut foo = HashMap::new();
foo.insert("bar", 42);
}
In C++, the declaration of `foo` would require a type annotation like `map<string_view, int>`. fn Default<T>::default() -> T
? Which is polymorphism, not overloading? Idk. Maybe I’m just being pedantic? fn main() {
foo((42));
foo((12.0, 13.0));
}
pub fn foo(args: impl FooArgs) { args.exec() }
pub trait FooArgs { fn exec(self); }
impl FooArgs for u32 { fn exec(self) { println!("A number: {}", self) } }
impl FooArgs for (f32, f32) { fn exec(self) { println!("{} x {} = {}", self.0, self.1, self.0 * self.1) } }
https://play.rust-lang.org/?version=stable&mode=debug&editio... A number: 42
12 x 13 = 156
Usually you won't abuse tuples quite like this, but it's an option. The same pattern of using traits - without the tuples - is more common [1]. Or if you need variadic functions, typically you'd resort to a macro instead.[1]: https://medium.com/@jreem/advanced-rust-using-traits-for-arg...