如何避免 Rust 中的硬编码值
How to avoid hard-coded values in Rust
下面是一个Maven/Java目录结构。
- src
- main
- java
- resources
- test
- java
- resources
- target
此处,resources 文件夹存放与应用程序相关的配置文件和资源文件,以避免在源文件中对其内容进行硬编码。
如何使用 Cargo 在 Rust 中实现相同的功能?
Maven 不包括您来源中的所有内容。事实上,它包含二进制文件,但甚至不必在 .jar
中包含源代码。您可以将其配置为说明要包含的内容,默认情况下是 resources
目录中的所有内容。
货物包源代码。 所有内容 都将包含在包装箱中,但与您的 .gitignore
文件匹配的内容除外。您可以通过在 [package]
部分添加 include
or exclude
条目,在 Cargo.toml
文件中对其进行微调。
要访问这些文件,有几个选项。
例如,如果您的项目如下所示:
- Cargo.toml
- src
- main.rs
- resources
- hello.txt
访问hello.txt
主要有以下三种方式。
include!
宏
使用 include!
宏,您可以像这样从 main.rs
访问 hello.txt
:
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 hello = std::fs::read_to_string("resources/hello.txt").unwrap();
这里的路径是相对于你的包的根目录的。这假设您从构建应用程序的地方 运行 使用 cargo run
连接应用程序。如果您正在部署二进制文件,您可能必须提供应用程序应在何处找到其资源的路径。
通常,这是首选方法。它更加灵活,因为您可以在 运行 时间交换配置或使用应用程序参数从不同位置加载。有很多用于解析不同文件格式的 crate,包括 json, toml 和许多其他格式。您可以控制您加载的数据的生命周期,因此您可以确保它在您完成后被释放。
下面是一个Maven/Java目录结构。
- src
- main
- java
- resources
- test
- java
- resources
- target
此处,resources 文件夹存放与应用程序相关的配置文件和资源文件,以避免在源文件中对其内容进行硬编码。
如何使用 Cargo 在 Rust 中实现相同的功能?
Maven 不包括您来源中的所有内容。事实上,它包含二进制文件,但甚至不必在 .jar
中包含源代码。您可以将其配置为说明要包含的内容,默认情况下是 resources
目录中的所有内容。
货物包源代码。 所有内容 都将包含在包装箱中,但与您的 .gitignore
文件匹配的内容除外。您可以通过在 [package]
部分添加 include
or exclude
条目,在 Cargo.toml
文件中对其进行微调。
要访问这些文件,有几个选项。
例如,如果您的项目如下所示:
- Cargo.toml
- src
- main.rs
- resources
- hello.txt
访问hello.txt
主要有以下三种方式。
include!
宏
使用 include!
宏,您可以像这样从 main.rs
访问 hello.txt
:
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 hello = std::fs::read_to_string("resources/hello.txt").unwrap();
这里的路径是相对于你的包的根目录的。这假设您从构建应用程序的地方 运行 使用 cargo run
连接应用程序。如果您正在部署二进制文件,您可能必须提供应用程序应在何处找到其资源的路径。
通常,这是首选方法。它更加灵活,因为您可以在 运行 时间交换配置或使用应用程序参数从不同位置加载。有很多用于解析不同文件格式的 crate,包括 json, toml 和许多其他格式。您可以控制您加载的数据的生命周期,因此您可以确保它在您完成后被释放。