在下面的示例中,模块outer具有私有(private)类型Private和私有(private)内部模块innerinner可以访问Private(因为子模块可以访问其父级的私有(private)项目,即使它们未作为公共(public) parking 场存放)。
inner定义一个函数not_really_public_interface()。虽然已将其标记为公共(public),但实际上仅可用于outer ,因为inner本身不是公共(public)的。

外在

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();
}

正确的?

斯特德
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认为“泄漏”的接口(interface)定义了一个函数,也不会产生任何错误。仅当outer尝试使用此功能时,才会发生该错误。
  • inner唯一可能“泄漏” Private的地方是定义它的模块。

  • 所以我的问题是:
  • 这里到底发生了什么,导致Rust认为该接口(interface)的任何部分泄漏了?似乎将Private视为已在inner中定义。
  • 是否有一个上下文可以说得通?我的第一个想法是,这是编译器中的错误,或者是隐私设计中的疏忽,但我怀疑情况确实如此。
  • 是否可以解决此问题而不创建另一个模块?我相信我可以创建一个包装器模块,然后在Privateouter中公开inner,但是我不想这样做。
  • 最佳答案

    函数not_really_public_interface是公共(public)的,因此可以被任何其他模块使用。但是Private结构只能由您的root和inner模块访问。

    如果另一个模块导入了not_really_public_interface,则会发生泄漏。 Rust提示这种情况可能会发生,因为它会在本地报告错误,而不是对所有模块和 crate 中的所有使用情况都采取“全局” View 。最终,这种方法对于人类来说是更可预测的,并且可以使机器推理得更快。

    Rust使您可以更精确地控制可见性。如果您告诉它该功能仅对上一级模块(super模块)可用,那么它将知道不存在泄漏的可能性:

    mod inner {
        use super::Private;
    
        pub(super) fn not_really_public_interface() -> Private { Private }
    }
    

    您也可以使用crate而不是super来表示同一包装箱中的任何模块。或者,如果 super 模块具有名称,例如my_mod,您可以使用pub(in ::my_mod)专门针对它。

    关于module - 返回私有(private)项目的私有(private)内部模块给出 “private type in public interface”错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50753923/

    10-12 04:23
    查看更多