在 Rust 中,我可以在不对值进行硬编码的情况下实例化我的 const 数组吗?编译时评估? [英] In Rust, can I instantiate my const array without hard-coding in the values? Compile-time evaluation?

查看:34
本文介绍了在 Rust 中,我可以在不对值进行硬编码的情况下实例化我的 const 数组吗?编译时评估?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Rust 中实例化一个数组.这是我可以在运行时执行的一种方法:

I'm trying to instantiate an array in Rust. Here's one way I could do it at runtime:

let mut t = [0_u32; 65];
for i in 0..t.len() {
    t[i] = ((i as f64).sin().abs() * 2.0_f64.powf(32.0)).floor() as u32;
}

然而,因为我永远不会改变这个数组的值,而且我会经常使用这些值,所以我认为这可能是一个很好的机会来探索 正在发生的很酷的事情const 编译时评估工作在 Rust 中完成.我可以让它在编译时计算数组并​​将结果存储在程序数据中,这样它就可以在运行时立即运行.

However, since I'm never going to change the values of this array and I'm going to use the values a lot, I thought this might be a good opportunity to explore the cool stuff going on with the const compile-time evaluation work being done in Rust. I could make it compute the array at compile time and just store the results in the program data so it's ready to go immediately at runtime.

我的第一步是创建常量数组.

My first step was to create the constant array.

const T: [u32; 65] = [0; 65];

好吧,这不好.我已经用全零实例化了它.那是不对的.接下来,我想也许我应该制作一个可以实例化数组的常量函数.

Well, this is no good. I've already instantiated it with all zeros. That's not right. Next, I thought maybe I should make a constant function that could instantiate the array.

const fn sine_table() -> [u32; 65] {
    let mut t = [0_u32; 65];
    let mut i = 0;


    loop {
        if i > 65 {
            break;
        }

        // Do the math...
    }

    t
}

这就是我卡住的地方.从我读到的内容来看,常量函数内的循环仍然只在夜间进行,我暂时尝试使用稳定的 Rust 以避免以后出现意外.那么,这让我何去何从?我目前可以在稳定的情况下做什么,以及在夜间、RFC 等中将有什么进展?我的下一个想法是研究宏,但我还不够舒服,无法在不知道它是否会有成果的情况下进入那个兔子洞.我的最终目标是让这个数组成为一个常量,而不必手动输入 65 个值.

And here's where I got stuck. From what I've read, loops inside constant functions are still only on nightly, and I'm trying to stick with stable Rust for the time being to avoid surprises later on. So, where does this leave me? What can I do currently in stable and what's coming down the pipeline in nightly, RFCs, etc.? My next thought was to investigate macros, but I'm not comfortable enough to go down that rabbit hole just yet without knowing if it'll be fruitful. My ultimate goal is to make this array a constant without having to type in 65 values by hand.

推荐答案

Cargo 支持在整体编译之前编译和运行的 build.rs 文件.对您来说,最简单的选择是使用它来生成您想要使用的表.

Cargo supports build.rs files that are compiled and run before the overall compilation. For you, the easiest option would be to use this to generate the table that you would like to use.

Rust 文档有一个例子 使用这种方法生成代码,所以如果你使用你的代码并用它来生成数组,你应该很高兴.您可以将 build = "build.rs" 放在您的 Cargo.toml 中,并使 build.rs 为:

The Rust docs have an example for code generation using this method, so if you take your code and use it to generate the array, you should be good to go. You can put build = "build.rs" in your Cargo.toml and have build.rs be:

use std::io::{Result, Write};

fn main() -> Result<()> {
  let out_dir = env::var("OUT_DIR").unwrap();
  let dest_path = Path::new(&out_dir).join("sin_abs_const.rs");
  let mut f = File::create(&dest_path).unwrap();

  write!(f, "const T: [u32; 65] = [\n")?;
  for i in 0..64 {
    write!(f, "  {},\n", ((i as f64).sin().abs() * 2.0_f64.powf(32.0)).floor() as u32)?;
  }
  write!(f, "];\n")?;

  Ok(())
}

然后你就可以加载那个构建的文件了.

then you can load that built file.

这篇关于在 Rust 中,我可以在不对值进行硬编码的情况下实例化我的 const 数组吗?编译时评估?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆