有什么方法可以将数据文件包含在 Rust 库中吗?

问题描述 投票:0回答:2

我正在尝试创建一个库,我想在其中包含一些二进制(或文本)文件,这些文件将包含在运行时解析的数据。我的目的是控制这些文件,不断更新它们,并在每次更新中更改库的版本。

可以通过货运吗?如果是这样,我如何从我的库中访问这些文件?

我想到的一个解决方法是包含一些带有结构和/或常量(如

.rs
)的
&str
文件,它将存储数据,但我发现它有点难看。


作者注:我已将接受的答案更改为更适合我的情况,但是请查看Shepmaster的答案,因为这可能更适合您的情况。

rust rust-cargo
2个回答
32
投票

免责声明:我在评论中提到过,但让我在这里重申一下,因为它给了我更多的空间来阐述。

正如 Shepmaster 所说,可以使用

include_bytes!
include_str!
宏将文本或二进制逐字包含在 Rust 库/可执行文件中。

但是,就你而言,我会避免它。通过将内容的解析推迟到运行时:

  • 您允许构建有缺陷的工件。
  • 您会产生(更多)运行时开销(解析时间)。
  • 您会产生(更多)空间开销(解析代码)。

Rust 承认这个问题,并提供了多种代码生成机制来克服这些限制:

  • 宏:如果逻辑可以编码成宏,那么它可以直接包含在源文件中
  • 插件:启动宏,可以编码任意逻辑并生成复杂的代码(参见
    regex!
  • build.rs
    :一个独立的“Rust 脚本”,在编译之前运行,其作用是生成
    .rs
    文件

就您而言,

build.rs
脚本听起来很合适:

  • 通过将解析代码移到那里,您可以交付更轻的工件
  • 通过提前解析,您可以交付更快的工件
  • 通过提前解析,您可以交付正确的工件

解析的结果可以用不同的方式编码,从函数到静态(可能是

lazy_static!
),因为
build.rs
可以生成任何有效的 Rust 代码。

您可以在

Cargo Documentation
中查看如何使用build.rs;您将在那里找到如何将其与 Cargo 集成以及如何创建文件(等等)。


26
投票

include_bytes!
宏似乎很接近你想要的。但它只为您提供对字节数组的引用,因此您必须从头开始进行任何解析:

static HOST_FILE: &'static [u8] = include_bytes!("/etc/hosts");

fn main() {
    let host_str = std::str::from_utf8(HOST_FILE).unwrap();

    println!("Hosts are:\n{}", &host_str[..42]);
}

如果您有 UTF-8 内容,则可以使用

include_str!
,正如 Benjamin Lindley 所指出的:

static HOST_FILE: &'static str = include_str!("/etc/hosts");

fn main() {
    println!("Hosts are:\n{}", &HOST_FILE[..42]);
}
© www.soinside.com 2019 - 2024. All rights reserved.