我有一个 struct :

pub struct OneDLookup <T: PartialOrd + Sub + Add + Copy + Clone, U: Add + Sub + Copy + Clone>{
    breakpoints: Vec<T>,
    values: Vec<U>,
    last_diff_bp: f64,      //ignore these, they are not important to this question
    last_diff_values: f64,
    first_diff_bp: f64,
    first_diff_values: f64,
}

这将起到查找表的作用,但是关于这个 struct 有两件重要的事情必须是真的:

断点必须按升序排列,例如1、5、7、9,而不能按任何其他顺序排列. 断点和值的长度必须相同.

是否可以在编译时(或者更好的做法是在编写期间使用 rust 蚀分析器)在宏中判断这些内容?我担心这可能不是.

我对Rust 还很陌生,所以我还在摸索细节.

我试着制作一个基于vec!()宏的不起作用的小宏,看看我是否能理解那里所做的事情,但不幸的是,我不知道:

macro_rules! create_1d_lookup {
    (($($bps:expr,)*); ($($vals:expr,)*)) => (
        $crate::my_crate::OneDLookup::new(vec![$($bps),+], vec![$($vals),+])
    );
}

OneDLookup::New()将断点和值矢量作为参数.

此 struct 是常量,在初始化后不会更改.

推荐答案

要做到这一点,您可以创建一个const,它运行一些逻辑来验证不变量是否被维护,如果它们被 destruct ,则会出现panic .死机将转化为编译失败:

macro_rules! create_1d_lookup {
    (($($bps:expr,)*); ($($vals:expr,)*)) => {{
        const _: () = {
            let breakpoints = [ $($bps,)* ];
            if breakpoints.len() != [ $($vals,)* ].len() {
                // There are multiple ways to count in macros,
                // this is the simplest assuming the expressions are side-effect-free.
                panic!("sizes of vectors don't match");
            }

            let mut i = 1;
            // Can't use a `for` loop in consts currently.
            while i < breakpoints.len() {
                if breakpoints[i - 1] > breakpoints[i] {
                    panic!("breakpoints aren't sorted");
                }
                i += 1;
            }
        };
        // $crate::my_crate::OneDLookup::new(vec![$($bps),+], vec![$($vals),+])
        OneDLookup::new(vec![$($bps),+], vec![$($vals),+])
    }};
}

不幸的是,这是一个后单态化错误,这意味着它不会出现在cargo check中,而只会出现在cargo build中.

Rust相关问答推荐

Tauri tauri—apps/plugin—store + zustand

将内部类型作为参数的泛型 struct 上的方法

"value is never read警告似乎不正确.我应该忽略它吗?

同时从不同线程调用DLL的不同函数会出现分段错误或产生STATUS_STACK_BUFFER_OVERRUN

在我的Cargo 中,当我在建筑物中使用时,找不到我可以在产品包中使用的 crate .r我如何解决这个问题?

如果包名称与bin名称相同,并且main.ars位于工作区的同一 crate 中,则无法添加对lib.ars的依赖

为什么`AlternateScreen`在读取输入键时需要按Enter键?

无法实现整型类型的泛型FN

为什么Option类型try块需要类型注释?

Rust移动/复制涉及实际复制时进行检测

Tokio';s io::用Cursor拆分<;Vec<;u8>>;赢得';t get the full writted data

我可以用 Rust 编写一个不可变变量

使用 Rust 从 Raspberry Pi Pico 上的 SPI 读取值

是否可以预测堆栈溢出?

在 Rust 中如何将值推送到枚举 struct 内的 vec?

如何解析 Rust 中的 yaml 条件字段?

我如何将 google_gmail1::Gmail> 传递给线程生成?

将数据序列化为 struct 模型,其中两个字段的数据是根据 struct 中的其他字段计算的

如何重写这个通用参数?

在同一向量 Rust 中用另一个字符串扩展一个字符串