如何在板条箱内公开 Rust 项目,但在板条箱外设为私有? [英] How do I make an Rust item public within a crate, but private outside it?

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

问题描述

我有一个包含大量代码的板条箱,因此我将其拆分为多个文件/模块.但是,某些模块具有内部不安全的内容(例如原始指针),我需要向不同的模块公开这些内容,但我不想向我的 crate 的用户公开.我该怎么做?

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?

我能想到的唯一方法就是让我的 crate 实际上只是一个大模块,但是除了 这个解决方案似乎有点老套.

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 文档中的简单示例并不能充分解释我只是复制一个流行的现实世界 crate,例如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.

推荐答案

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

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.

自从 Rust 1.18,有一个适合这种场景的解决方案:pub(restricted).此功能可让您指定项目应该公开的程度".语法非常灵活(你可以让一个项目对特定的模块树而不是整个 crate 可见),但是如果你想保持简单,pub(crate) 将使一个项目可以在任何地方访问在 crate 内,但不在其他 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 的情况.例如,如何使导出结构的某些字段可以在同一个 crate 中的其他模块中访问而不导出它们?唯一的选择是公开一个带有单个私有字段的包装器,其类型是具有公共字段的结构;如果您想隐藏其他 crate 中的所有字段,这可以正常工作,但如果您想公开某些字段并且在同一结构中使其他一些字段成为内部字段,则效果很好.

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天全站免登陆