这个问题在这里已经有了答案:
How do I make an Rust item public within a crate, but private outside it?
(1 个回答)
1年前关闭。
要将子模块中的方法公开,您必须显式重新导出它们,否则将子模块本身公开:
mod foo {
mod bar {
pub fn baz() {}
}
pub use self::bar::baz;
}
这似乎暗示 pub
用于指示事物应该只对模块公开(因为您可以选择不这样做)但是,如果您使用在外部上下文中定义的私有(private)类型,如果您尝试在内部上下文中将涉及它的公共(public)函数设为公共(public),即使它没有重新导出,也会出现错误。
mod foo {
struct Foo;
mod bar {
use super::Foo;
pub fn baz(foo: Foo) {}
}
}
结果是error[E0446]: private type `Foo` in public interface
--> src/lib.rs:7:9
|
2 | struct Foo;
| - `Foo` declared as private
...
7 | pub fn baz(foo: Foo) {}
| ^^^^^^^^^^^^^^^^^^^^ can't leak private type
使用 pub
的惯用方式是什么?关键词?它应该保留给实际公开的东西还是可以用于内部模块?
最佳答案
您的示例无法编译的原因最终是因为 RFC (136)我说过了。 (另见 issue 22261)
What restrictions apply to public items?
The rules for various kinds of public items are as follows:
- If it is a
static
declaration, items referred to in its type must be public.- If it is an
fn
declaration, items referred to in its trait bounds, argument types, and return type must be public.- If it is a
struct
orenum
declaration, items referred to in its trait bounds and in the types of itspub
fields must be public.- If it is a
type
declaration, items referred to in its definition must be public.- If it is a
trait
declaration, items referred to in its super-traits, in the trait bounds of its type parameters, and in the signatures of its methods (seefn
case above) must be public.
简而言之,
baz
不允许为pub
因为它有一个私有(private)类型的参数。因此,如果 baz
是 pub
它将允许父 mod foo
转口baz
通过做pub use bar::baz;
.这当然是不允许的,这也是整个示例非法的原因。有些人之前提到过
pub fn baz
应该允许,而是在父模块重新导出它的情况下给出编译错误。然而,这将需要更复杂的静态分析来检测,并且最终没有完成,因为 RFC 定义它是非法的。pub
指定项目可由父模块访问。如果所有模块祖先都是pub
,然后该项目由 crate 作为一个整体导出。The keyword
pub
makes any module, function, or data structure accessible from inside of external modules. Thepub
keyword may also be used in ause
declaration to re-export an identifier from a namespace.
With the notion of an item being either public or private, Rust allows item accesses in two cases:
- If an item is public, then it can be accessed externally from some module m if you can access all the item's ancestor modules from m. You can also potentially be able to name the item through re-exports. See below.
- If an item is private, it may be accessed by the current module and its descendants.
关于rust - `pub` 是表示 public-to-crate 还是 public-to-module?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65296435/