rust - 如何编写一个转发到 vec 的可变 Rust 宏!宏?

标签 rust vector macros variadic

在 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);
    }
}

Rust Playground

这利用了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![];

Playground.

关于rust - 如何编写一个转发到 vec 的可变 Rust 宏!宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75994633/

相关文章:

rust - 使用 Iron 在简单的 Web 服务器中调用两次的函数

rust - Rust future 中的 `then` 、 `and_then` 和 `or_else` 有什么区别?

rust - 使用类型作为不同的名称和类型别名有什么区别?

c++ - 编译多个 C++,获取未初始化的 vector

c++ - 通过宏定义一个 Enum/Struct 需要什么?

c - 有没有办法用 C 宏代替普通的 C 代码

rust - 使用函数指针时为 "Expected fn item, found a different fn item"

多次调用函数中的c++大 vector

c++ - 运算符 "!="不匹配(c++ 迭代器)

plugins - 如何从过程宏中处理扩展宏?