Gostaria de escrever uma add
função que possa receber como entrada um i64
ou f64
dois parâmetros.
Consegui chegar ao seguinte:
use std::ops::Add;
fn add<T: Add<Output = T>>(a: T, b: T) -> T{
a + b
}
fn main() {
let a: i64 = 10;
let b: i64 = 20;
let c: f64 = 10.5;
let d: f64 = 20.5;
println!("{:?}", add(a, b)); // Outputs: 30
println!("{:?}", add(c, d)); // Outputs: 31.0
}
É possível modificar esta função para que seja possível ter:
- um parâmetro sendo um
i64
- o outro parâmetro é um
f64
Se qualquer um dos parâmetros for um, f64
fazemos uma conversão e retornamos um f64
.
tipo dea |
tipo deb |
retornoutype |
---|---|---|
i64 |
i64 |
i64 |
i64 |
f64 |
f64 |
f64 |
i64 |
f64 |
f64 |
f64 |
f64 |
A função principal teria a seguinte saída:
fn main() {
let a: i64 = 10;
let b: i64 = 20;
let c: f64 = 10.5;
let d: f64 = 20.5;
println!("{:?}", add(a, b)); // Outputs: 30 | i64 + i64 -> i64
println!("{:?}", add(a, c)); // Outputs: 20.5 | i64 + f64 -> f64
println!("{:?}", add(c, a)); // Outputs: 20.5 | f64 + i64 -> f64
println!("{:?}", add(c, d)); // Outputs: 30.0 | f64 + f64 -> f64
}
Você pode fazer isso usando um trait. O trait pode ser idêntico ao trait embutido
Add
, mas devido à regra órfã você não pode usar oAdd
trait em si. Aqui está um exemplo de implementação:Parque infantil
A regra órfã impede que você implemente traços estrangeiros em tipos estrangeiros. O código acima contorna isso usando um traço personalizado. Como alternativa, você pode usar tipos personalizados, ou seja, wrappers newtype em torno de
i64
ef64
. Como a implementação corresponde à implementação interna de adição, seria suficiente encapsular um dos dois tipos em um wrapper newtype.