rust - `pub` 是表示 public-to-crate 还是 public-to-module?

标签 rust visibility conventions

这个问题在这里已经有了答案:





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 or enum declaration, items referred to in its trait bounds and in the types of its pub 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 (see fn case above) must be public.

简而言之,baz不允许为pub因为它有一个私有(private)类型的参数。因此,如果 bazpub它将允许父 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. The pub keyword may also be used in a use declaration to re-export an identifier from a namespace.

Rust Documentation


With the notion of an item being either public or private, Rust allows item accesses in two cases:

  1. 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.
  2. If an item is private, it may be accessed by the current module and its descendants.

The Rust Reference - Visibility and Privacy

关于rust - `pub` 是表示 public-to-crate 还是 public-to-module?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65296435/

相关文章:

vector - 如何将迭代器元素的类型强制转换为新类型?

rust - 如何在 Rust 中借用可变与不可变?

python - 在同时运行的两个函数中访问同一对象的属性

objective-c - 类别可以访问在它扩展的类中定义的实例变量吗?

java - 这个 Actor 好吗?

java - 正确结束Java命令行应用

rust - 自有指针移动的语义

rust - 在 MIO 中检测客户端挂断

android View with View.GONE 仍然接收 onTouch 和 onClick

c# - 关于 GUI 与逻辑类集成方式的一个非常基本的问题