如何将Rust物品在箱子内公开,但在箱子外私人呢? [英] How do I make an Rust item public within a crate, but private outside it?

查看:285
本文介绍了如何将Rust物品在箱子内公开,但在箱子外私人呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的箱子里有很多代码,因此我将其拆分为多个文件/模块.但是,有些模块具有内部不安全的内容(例如,原始指针),我需要将它们公开给不同的模块,但是我不想向我的板条箱用户公开.我该怎么办?

I have a crate that has lots of code, so I've split it into multiple files/modules. However, some modules have internal unsafe stuff (e.g. raw pointers) that I need to make public to the different modules, but I don't want to expose to users of my crate. How can I do that?

我能想到的唯一方法是将包装箱实际上是一个大模块,但是除了

The only way I can think of is to actually have my crate just be one big module, but then there's no way to split it into different files, other than this solution which seems a bit hacky.

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

Normally when I come up against a real world problem that the simple examples in the Rust docs don't adequately explain I just copy a popular real world crate, e.g. git2-rs, but that just seems to effectively make everything public, including the raw pointers.

推荐答案

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

In order for an item to be exported from a library crate, there must be at least one path leading to it in which every component is public. This means that all you need to make an item public within your crate but not exported from the crate (I'll call this "internal" from now on, to mimic C# terminology) is to put it in a private module under the crate root.

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

However, that solution is quite restrictive. What if you'd like to have a module with exported functions and internal functions? In order to export some functions, we need to make the module public, and that mean all public items in that module will be exported as well.

铁锈1.18 ,有一种适用于这种情况的解决方案:pub(crate)将使条板箱内的任何位置均可访问该项目,而对其他项目则不可见板条箱(相当于C#中的internal).

Since Rust 1.18, there's a solution adapted to this kind of scenario: pub(restricted). This feature lets you specify "how public" an item should be. The syntax is pretty flexible (you can make an item visible to a particular module tree instead of the whole crate), but if you want to keep it simple, pub(crate) will make an item accessible anywhere within the crate, but not to other crates (equivalent to internal in C#).

例如,假设我们要有一个模块util,其中导出foo(作为mycrate::util::foo),bar是内部的,而baz是该模块的私有模块.代码可能看起来像这样:

For example, suppose we'd like to have a module util in which foo is exported (as mycrate::util::foo), bar is internal and baz is private to the module. The code might look like this:

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

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

    fn baz() {
        unimplemented!()
    }
}


如果您坚持使用1.18之前的Rust,可以使用一种解决方法,但是有点笨拙.它涉及在私有模块中定义所有项目,并仅将要公开的项目(使用pub use)重新导出到仅包含 的公共模块中.上面的示例如下所示:


If you're stuck on pre-1.18 Rust, there's a workaround, but it's a bit clunky. It involves defining all your items in private modules, and reexporting only those that you want to make public (with pub use) in public modules that only contain reexports. Here's what the example above would look like:

pub mod util {
    pub use util_impl::foo;
}

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

    pub fn bar() {
        unimplemented!()
    }

    fn baz() {
        unimplemented!()
    }
}

这不仅不容易阅读和理解,还不能涵盖所有可以使用pub的情况.例如,如何使导出的结构的某些字段在同一板条箱中的其他模块中可访问而又不导出它们?唯一的选择是使用单个私有字段公开包装器,该私有字段的类型是具有公共字段的结构.如果您想隐藏其他包装箱中的所有字段,那么效果很好,但是如果您想暴露某些字段 并使其他字段位于同一结构中,则效果很好.

Not only is this not easy to read and understand, it doesn't cover all situations where pub can be used. For example, how would you make some fields of an exported struct accessible in other modules in the same crate without also exporting them? The only option would be to expose a wrapper with a single private field whose type is the struct that has public fields; that works fine if you want to hide all fields from other crates, but not if you want to expose some fields and make some other fields internal in the same struct.

这篇关于如何将Rust物品在箱子内公开,但在箱子外私人呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆