module - 如何在 crate 中将 Rust 项目设为公开,但在其外部设为私有(private)?

标签 module rust public rust-crates

我有一个有很多代码的 crate ,所以我把它分成了多个文件/模块。但是,某些模块具有内部不安全的东西(例如原始指针),我需要将其公开给不同的模块,但我不想暴露给我的 crate 的用户。我怎样才能做到这一点?

我能想到的唯一方法是让我的 crate 成为一个大模块,但是除了 this solution 之外,没有办法将它拆分为不同的文件。这似乎有点hacky。

通常,当我遇到一个真实世界的问题时,Rust 文档中的简单示例无法充分解释我只是复制一个流行的真实世界的箱子,例如git2-rs ,但这似乎只是有效地公开了所有内容,包括原始指针。

最佳答案

为了获得 item要从库 crate 中导出,必须至少有一条通向它的路径,其中每个组件都是公共(public)的。这意味着您需要在您的 crate 中公开一个项目但不从 crate 中导出(我从现在开始将其称为“内部”,以模仿 C# 术语)是将它放在 crate 根目录下的私有(private)模块中.

但是,该解决方案具有很大的限制性。如果您想要一个具有导出函数和内部函数的模块怎么办?为了导出某些功能,我们需要将模块设为公共(public),这意味着该模块中的所有公共(public)项也将被导出。

Rust 1.18 ,有适合这种场景的解决方案: pub(restricted) .此功能可让您指定项目的“公开程度”。语法非常灵活(你可以让一个项目对特定的模块树而不是整个 crate 可见),但如果你想保持简单,pub(crate)将使项目可以在 crate 中的任何地方访问,但不能访问其他 crate(相当于 C# 中的 internal)。

例如,假设我们想要一个模块 util其中foo被导出(作为 mycrate::util::foo ),bar是内部的,baz是模块私有(private)的。代码可能如下所示:

pub mod util {
    pub fn foo() {
        unimplemented!()
    }

    pub(crate) fn bar() {
        unimplemented!()
    }

    fn baz() {
        unimplemented!()
    }
}

如果你被 1.18 之前的 Rust 卡住了,有一个解决方法,但它有点笨拙。它涉及在私有(private)模块中定义所有项目,并仅在仅包含重新导出的公共(public)模块中重新导出您想要公开的项目(使用 pub use )。上面的示例如下所示:
pub mod util {
    pub use util_impl::foo;
}

mod util_impl {
    pub fn foo() {
        unimplemented!()
    }

    pub fn bar() {
        unimplemented!()
    }

    fn baz() {
        unimplemented!()
    }
}

这不仅不容易阅读和理解,而且没有涵盖 pub 的所有情况。可以使用。例如,如何使导出结构的某些字段在同一个 crate 中的其他模块中可访问,而不导出它们?唯一的选择是公开一个带有单个私有(private)字段的包装器,其类型是具有公共(public)字段的结构;如果您想从其他 crate 中隐藏所有字段,这很好用,但如果您想公开一些字段并在同一个结构中创建一些其他字段,则不行。

关于module - 如何在 crate 中将 Rust 项目设为公开,但在其外部设为私有(private)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62048181/

相关文章:

python - Python 是否有用于编写命令行任务脚本的模块?

javascript - NodeJs 堆 js 模块 : Heap is not a constructor

javascript - 何时在 TypeScript 中使用脚本标签包含 JS 库?

javascript - Node.js、Express、Redis - 无法调用来自单独模块的路由

rust - `paint_evm::Event` 未针对 `Event` 实现

android - 为什么 fragment 类应该公开?

c++ - C++中类或函数的可访问性是如何控制的

rust - 如何将 tokio::timer::Timeout 与 Future::wait 一起使用?

rust - 在此示例中,str和String::from有什么区别? [复制]

java - 何时使用本地访问修饰符?