如何避免Rust中的硬编码值

时间:2017-09-29 09:42:55

标签: rust rust-cargo

下面是Maven / Java目录结构。

- src
  - main
    - java
    - resources
  - test
    - java
    - resources

- target

此处,资源文件夹包含与应用程序相关的配置文件和资源文件,以避免在源文件中对其内容进行硬编码。

如何在Rust with Cargo中实现相同目标?

1 个答案:

答案 0 :(得分:2)

Maven并不包含您来源的所有内容。实际上,它包含二进制文件,但甚至不必在.jar中包含源代码。您可以将其配置为说明要包含的内容,默认情况下是resources目录中的所有内容。

货物包源代码。 Everything 将包含在包中,但与.gitignore文件匹配的内容除外。您可以在Cargo.toml文件中对其进行微调,方法是在[package]部分添加include or exclude条目。

要访问这些文件,有几个选项。

例如,如果您的项目如下所示:

- Cargo.toml
- src
   - main.rs
- resources
   - hello.txt

有三种主要方式可以访问hello.txt,如下所示。

include!

使用include!宏,您可以从hello.txt访问main.rs,如下所示:

let hello: &str = include!("../resources/hello.txt");

请注意,宏将直接在源文件中包含文件,就像您复制&粘贴文件的内容。所以我给出的例子只有在文件内容包含""引号时才有效。任何Rust源都可以去那里,并且必须在编译时包含它。这可以方便地包含复杂的Rust结构,而不必编写解析代码。请注意,该路径是相对于包含它的源.rs文件。

include_bytes!include_str!

include_bytes!宏从文件中创建一个固定大小的u8数组,以便在编译时包含。

let bytes = include_bytes!("../resources/hello.txt").
let hello: String = String::from_bytes_lossy(bytes).to_string();

这样可以方便地将任意二进制数据合并到您的应用程序中,例如图像,而无需在运行时加载它。该数组的生命周期为'static,因此将在应用程序的整个生命周期内保留在内存中。

include_str!宏的工作方式类似,但会产生一个字符串切片,生命周期为'static

在运行时

要在运行时加载文件,您可以使用:

let mut contents: String = String::new();
let mut file: File = File::open("resources/hello.txt").unwrap();
file.read_to_string(&mut contents).unwrap();

let hello = contents;

这里的路径是相对于您的箱子的根。假设您使用cargo run运行应用程序来构建它。如果要部署二进制文件,则可能必须提供应用程序应找到其资源的路径。

通常,这是首选方法。它更灵活,因为您可以在运行时交换配置或使用应用程序参数从其他位置加载。有许多用于解析不同文件格式的包,包括jsontoml和其他许多文件格式。您可以控制所加载数据的生命周期,因此您可以确保在完成后将其解除分配。