在 Rust 2021 中,我有一个名为 Intersection
的结构类型,并且我希望将其存储在可变长度列表中,因此可能是 Vec<Intersection>
。我可以轻松地构建一个新容器:
#[derive(Debug)]
struct Intersection {
t: f64,
// ...
}
fn main () {
let i0 = Intersection { t: 0.1 };
let i1 = Intersection { t: 0.2 };
let vs = vec!(i0, i1);
for v in vs {
println!("{:?}", v);
}
}
这利用了vec!
宏。
我现在想做的是稍微抽象一下容器类型,将实现( Vec<>
)与 API 用户分离。目前,为了以侵入性最小的方式做到这一点,我可以使用类型别名来鼓励解耦:
type Intersections = Vec<Implementation>;
为了补充这一点,我还想定义一个辅助函数,以从可变数量 Intersection
创建这样的集合。对象。所以可以这样使用:
fn main () {
let i0 = Intersection { t: 0.1 };
let i1 = Intersection { t: 0.2 };
let i2 = Intersection { t: 0.3 };
let vs = intersections(i0, i1, i2); // <--- what can this be?
for v in vs {
println!("{:?}", v);
}
}
换句话说,我希望将可变数量的参数转发给函数 intersections()
到vec!
宏。不过我知道 Rust 不支持可变参数,所以我需要编写一个调用 vec!
的宏。在内部,也许可以将其称为 intersections!(&i0, &i1, ...)
.
我查看了标准库的 vec!
的实现我不确定如何将项目列表转发到 vec!
宏。
我很感激,因为我使用类型别名,所以我可以调用 vec!(...)
直接,但是我想将接口(interface)与 Vector 解耦,这样如果我更改容器实现,我可以更改 intersections()
函数或intersections!
宏以适应新的实现。这在 C、C++、Haskell 等中是很常见的事情,因此可以稍后重新定义类型。
最佳答案
您可以简单地编写一个包装宏来转发到 vec!
的现有规则。宏:
macro_rules! intersection {
() => { vec![] };
($elem:expr; $n:expr) => { vec![$elem; $n] };
($($x:expr),+ $(,)?) => { vec![$($x),+] };
}
然后您可以像这样调用您的 intersection!
宏,例如:
let vs = intersection![i0, i1];
// requires Intersection to implement Clone
let vs = intersection![Intersection { t: 0.1} ; 2];
let vs: Intersections = intersection![];
关于rust - 如何编写一个转发到 vec 的可变 Rust 宏!宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75994633/