我的箱子里有很多代码,因此我将其拆分为多个文件/模块。但是,有些模块具有内部不安全的内容(例如,原始指针),我需要将它们公开给不同的模块,但是我不想向我的 crate 用户公开。我怎样才能做到这一点?

我能想到的唯一方法是实际上将我的箱子变成一个大模块,但是除了this solution似乎有点hacky之外,没有办法将其拆分为不同的文件。

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

最佳答案

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

但是,该解决方案非常严格。如果您想要一个带有导出功能和内部功能的模块怎么办?为了导出某些功能,我们需要将模块公开,这意味着该模块中的所有公共(public)项目也将被导出。

Rust 1.18开始,有一种适用于这种情况的解决方案: pub(restricted) 。此功能使您可以指定项目的“公开程度”。语法非常灵活(您可以使项目对特定的模块树而不是整个条板箱可见),但是如果您想保持简单,pub(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)字段公开包装器,该私有(private)字段的类型是具有公共(public)字段的结构。如果您想从其他包装箱中隐藏所有字段,则效果很好,但是如果您想公开某些字段并使其他某些字段位于同一结构中,则效果不是很好。

关于module - 如何将Rust物品在箱子内公开,但在箱子外私有(private)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41666235/

10-12 03:28