rust - 如何使用通用输入类型和多个/可选输入参数创建函数
问题描述
假设我将以下函数作为基线:
fn sum(a: i32, b: i32) -> i32 {
a + b
}
我想用一个函数替换它:
- 接受不同类型的数值输入参数(i32、f64、..)
- 用户输入时接受不同数量的输入参数,2,3,4,...
- 能做4个基本的数学运算
- 仅返回 3 位小数的结果
即如何编写单个函数来运行以下2条语句:
let x = sum(2, 3.1);
let y = sum(4.2, 6.3, 5.2, 10);
解决方案
我发现最好的方法是做macro
,下面是我的方法,欢迎其他答案:
macro_rules! sum{
($($element:expr); *) => [
{
let mut sum = 0f64;
$(sum += $element as f64;)*
sum
}
];
}
macro_rules! sub{
($first:expr, $($others:expr); *) => [
{
let mut sub = $first as f64;
$(sub -= $others as f64;)*
sub
}
];
}
macro_rules! mul{
($($element:expr), *) => [{
let mut mul = 1f64;
$(mul *= $element as f64;)*
format!("{:.3}", mul).parse::<f64>().unwrap()
}];
}
macro_rules! div{
($first:expr, $second:expr) => [
$first as f64 / $second as f64
];
}
macro_rules! math{
($op: expr, $first:expr, $($others:expr), *) => {
match $op {
"+" => {
let mut sum = $first as f64;
$(sum += $others as f64;)*
Ok(sum)
},
"-" => {
let mut sub = $first as f64;
$(sub -= $others as f64;)*
Ok(sub)
},
"*" => {
let mut mul = $first as f64;
$(mul *= $others as f64;)*
Ok(mul)
}
"/" => {
let mut div = $first as f64;
$(div /= $others as f64;)*
Ok(div)
},
_ => Err("no correct operation selected"),
}
};
}
fn main() {
println!("{}", math!("+", 1, 2).unwrap());
match math!("+", 1, 2) {
Err(e) => println!("Error found: {error}", error = e),
Ok(r) => println!("Result found: {result}", result = r),
};
println!("{:.3}\n{:.3}\n{}\n{:.3}", sum!(1, 2.1, 3), sub!(1, 2.7, -3), mul!(2.12588, 3.5), div!(2.5, 3) );
}
推荐阅读
- npm - 如何将带有+登录版本(Semver 2.0.0)的包发布到npm?
- android - 我已经创建了 React 本机应用程序并将其构建为独立的 android apk 文件,但如果不连接到同一网络,我将无法使用它
- visual-studio - 在安装项目中更改了版本,但它仍然不会重新安装?
- mongodb - 努力对 NO-SQL 进行复杂查询
- python - Pandas 数据框中的 Edgelist 使用 networkx 进行可视化
- python-3.x - 给定Python中的变换矩阵,如何将区域转换为原始空间
- python - Python:将 CSV 列解析为 np.array 的行和列索引?
- python - Pandas 中是否有一种方法可以使用已修改的列合并两个数据框而不影响原始数据?
- codeigniter-4 - Codeigniter 4如何显示某个名称出现在X行以上的记录
- c# - C# 中的 PSOC 端口连接