首页 > 解决方案 > 如何使用通用输入类型和多个/可选输入参数创建函数

问题描述

假设我将以下函数作为基线:

fn sum(a: i32, b: i32) -> i32 {
    a + b
}

我想用一个函数替换它:

  1. 接受不同类型的数值输入参数(i32、f64、..)
  2. 用户输入时接受不同数量的输入参数,2,3,4,...
  3. 能做4个基本的数学运算
  4. 仅返回 3 位小数的结果

即如何编写单个函数来运行以下2条语句:

let x = sum(2, 3.1);
let y = sum(4.2, 6.3, 5.2, 10);

标签: rust

解决方案


我发现最好的方法是做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) );
}

推荐阅读