2

So I wrote this macro in Rustlang to allow me to create multiple functions fast that accepts a bunch of values and then perform an arithmetic operation (or may be other operations, hence the need for it to remain dynamic enough) on them this way special_fn!(add, 4, i32, +);

Here is the code.

#[macro_export]
macro_rules! special_fn {
    ($func:ident, $n:expr, $t:ty, $op:tt) => {

        pub fn $func(values : Vec<$t>) -> $t{
            let mut result:$t;
             for x in 1..$n {
                result $op= values[x];
            }
            result
        }

    };
}

But this line is causing issues result $op= values[x]; and it says Expleced expression, found = enter image description here

However,

  • I could use match expression or if expression to match all possible operations, but that will require more code
  • I also found another way is this
macro_rules! special_fn {
    ($func:ident, $n:expr, $t:ty, $op:tt, $default:expr) => {

        pub fn $func(values : Vec<$t>) -> $t{
            let mut result:$t = $default;
             for x in 1..$n {
                result = result $op values[x];
            }
            result
        }

    };
}

But this will introduce another metavariable to the macro. Is there another way that will keep the simplicity?

Henry Obiaraije
  • 301
  • 3
  • 10
  • 2
    Note that you need default value anyway, since `result += value` and friends isn't valid when `result` is uninitialized. – Cerberus Mar 11 '23 at 16:35

1 Answers1

0

You cannot concatenate = to an operator captured in tt (without a proc macro). += is a single token, and if you do $op= it's like if you type + =, which is invalid (I think a proc macro could do that, but I haven't tested).

You could pass += to the macro instead of +, but as @Cerberus said, you need a default value anyway so just pass it (or use Default::default()).

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77