如何使用宏将元组展开为函数参数?

5

我有一个来自外部库[1]的函数,类似于:

fn set_color(r: f64, g: f64:, b: f64)

我想使用元组来管理我的颜色,例如:

let yellow = (1., 1., 0.);

我考虑了一个类似于以下的宏:

macro_rules! rgb {
    ( $rgb:expr ) => { rgb.0, rgb.1, rgb.2 }
}

游乐场

然后

set_color(rgb!(yellow));

不幸的是,Rust 报错:error: macro expansion ignores token ',' and any following

我该怎么做呢?


[1]: cairo::Context::set_source_rgb() 和其他相关函数


2
出于好奇,你为什么需要一个宏来完成这个任务?一个函数不足以满足需求吗?例如 fn rgb(color_tup: (f64, f64, f64)) - chub500
1
据我理解,@chub500的意思是OP不想在每个函数调用中都进行元组拆包。 - Shepmaster
我想为这个包装器取一个更好的名字,可能是fn set_color_tup(color: (f64, f64, f64))。我认为这是一个很好的元组结构体使用案例。如果OP担心性能问题,那么这个内联函数应该与宏完全相同。 - chub500
1
如果只是一个函数,我可以包装它。但是 cairo:: 有很多类似的函数。 - Johannes Mueller
啊,这就是我所缺少的。谢谢! - chub500
显示剩余2条评论
1个回答

8

你做不到这点。Rust宏并不像执行愚蠢的文本操作的C宏;Rust宏必须生成有效的调用代码,但a、b、c无效。

最接近的方法是将函数传递给宏:

macro_rules! rgb {
    ($f:expr, $rgb:expr) => {
        $f($rgb.0, $rgb.1, $rgb.2)
    };
}

let white = (1., 1., 1.);
rgb!(set_color, white);

我认为一个普通的函数也可以完成这个任务。fn rgb<T>(f: fn(f64, f64, f64) -> T, color: (f64, f64, f64)) -> T - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接