如何通过在 Rust 中调用它们的方法来避免重复重新声明变量?

How to avoid repetition re-declaring variables by calling their methods in Rust?

我在 Rust 中对多个参数使用 Into 并希望避免许多赋值和愚蠢的错误。

pub fn my_fancy_function<T>(v: T, u: T, i: T, l: T, j: T)
    where T: Into<MyStruct>
{
    let v = v.into();
    let u = u.into();
    let i = l.into(); // Oops, I transposed these!
    let l = i.into();
    let j = j.into();
    // some code
}

有没有办法避免写出大块的作业?一个宏也许可以做到这一点:

expand_into!(v, u, i, l, j);

into() 方法没有什么特别之处,它只是一个示例,您可能经常以一种可以轻松删除重复的方式在函数的开头重新声明许多参数。

当然,您可以使用递归宏来完成此操作:

macro_rules! expand_into {
    () => ();
    ($head:ident $(, $tail:ident)*) => (
        let $head = $head.into();
        expand_into!($($tail),*);
    );
}

并对其进行测试:

fn main() {
    let a = 1;
    let b = 2;
    let c = 3;
    let d = 4;

    expand_into!(a, b, c, d);

    // Need to do something that reveals types so the compiler knows
    // which `into()` functions to call.
    if let (Some(x), Some(y), Some(z), Some(w)) = (a, b, c, d) {
        println!("{}, {}, {}, {}", x, y, z, w);
    }
}

如@paholg 所述,您可以使用宏轻松完成此操作。然而,你不需要使用递归,递归会慢一点,用处也少一点(你只能在编译器放弃之前递归有限的次数)。

我还冒昧地使用了 Into::into 方法的完全限定名称,以避免名称冲突问题:

macro_rules! expand_into {
    ($($names:ident),*) => {
        $(let $names = ::std::convert::Into::into($names);)*
    };
}