在下面的示例中,模块outer
有一个私有类型Private
和一个私有内部模块inner
. inner
能够访问Private
(因为子模块可以访问其父模块的私有项目,即使它们不是公共停车)。
inner
定义一个函数not_really_public_interface()
。虽然它被标记为公开,它实际上只适用于outer
因为inner
本身并不公开。
outer.rs
struct Private;
mod inner {
use super::Private;
pub fn not_really_public_interface() -> Private {
Private
}
}
这编译没有任何问题。
outer
应该可以使用inner::not_really_public_interface()
获得Private
,只要确保不导出即可。那么让我们这样做:
pub fn main() {
let _ = self::inner::not_really_public_interface();
}
Right?
stderr
error[E0446]: private type `Private` in public interface
--> src/outer.rs:4:3
|
4 | / pub fn not_really_public_interface() -> Private {
5 | | Private
6 | | }
| |___^ can't leak private type
Wat.这对我来说是违反直觉的,原因如下:
- 前面的代码不会产生错误,即使它定义了一个带有 Rust 认为“泄漏”的接口的函数。该错误仅发生在
outer
尝试use这个功能。
- 唯一的地方
inner
可能会“泄漏”Private
is to 定义它的模块.
所以我的问题是:
- 这里究竟发生了什么,导致 Rust 得出此接口的任何部分存在泄漏的结论?好像可以治疗
Private
就好像它被定义在inner
.
- 是否有一个上下文可以让这句话完全有意义?我的第一个想法是这是编译器中的错误或隐私设计中的疏忽,但我怀疑情况确实如此。
- 有没有办法在不创建另一个模块的情况下解决这个问题?我相信我可以创建一个包装模块,然后制作
Private
内部公开outer
and inner
,但我不想这样做。
功能not_really_public_interface
is公共所以它可以被使用any其他模块。但是Private
struct 只能由您的 root 访问并且inner
模块。
如果导入另一个模块就会发生泄漏not_really_public_interface
。 Rust 抱怨说这could发生这种情况是因为它在本地报告错误,而不是对所有模块和板条箱中的所有用法采取“全局”视图。最终,这种方法对于人类来说推理起来更具可预测性,对于机器来说速度更快。
Rust 可以让你更精确地控制可见性。如果你告诉它这个函数是only可供上一级模块使用(super
module) 那么它就知道不存在泄漏的可能性:
mod inner {
use super::Private;
pub(super) fn not_really_public_interface() -> Private { Private }
}
你也可以使用crate
代替super
,表示同一个 crate 中的任何模块。或者,如果超级模块有一个名称,例如my_mod
,你可以使用pub(in ::my_mod)
专门针对它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)