So I did manage to make a generic function where I can use the default types:
fn arithmetic_operation<T, F>(a: T, b: T, operation: F) -> T
where
T: Copy,
F: Fn(T, T) -> T,
{
operation(a, b)
}
fn main() {
// f64
let result_f64 = arithmetic_operation(2.0, 3.0 , |x, y| x+y);
println!("Result f64: {:?}", result_f64);
// Result f64: 5.0
// i128
let result_i128 = arithmetic_operation(2i128, 3i128 , |x, y| x+y);
println!("Result i128: {:?}", result_i128);
// Result i128: 5
}
playground
I would like to create some custom types (like money, km, …) and still use generic functions. But I can’t figure out how to write a function signature for custom types.
If I write a custom type defined with an enum:
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum ResType {
Int(i128),
Float(f64),
}
impl ResType {
fn get_i128(self) -> i128 {
match self {
ResType::Int(val) => val,
ResType::Float(val) => val as i128
}
}
fn get_f64(self) -> f64 {
match self {
ResType::Int(val) => val as f64,
ResType::Float(val) => val
}
}
fn is_float(&self) -> bool {
matches!(self, ResType::Float(_) )
}
}
fn arithmetic_operation<T, F>(a: ResType, b: ResType, func: F) -> ResType
where
T: Copy,
F: Fn(T, T) -> T,
{
if a.is_float() || b.is_float() {
let res = func(a.get_f64(), b.get_f64());
return ResType::Float(res);
}
let res = func(a.get_i128(), b.get_i128());
ResType::Int(res)
}
fn main() {
let a = ResType::Int(42);
let b = ResType::Int(13);
println!("Result ResType: {:?}", arithmetic_operation(a, b, |x,y| x+y));
}
playground
I have some errors explaining that a T is required, but an f64 is given.
note: expected type parameter `T`, found `f64`
--> src/main.rs:33:24
|
33 | let res = func(a.get_f64(), b.get_f64());
| ^^^^^^^^^^^
= note: expected type parameter `T`
found type `f64`
How can I make this type of generic function work with a custom type ?
Or is this a wrong approach altogether to create new types ?