pub 和 pub(super) 何时具有不同的语义?

Jos*_*vin 5 encapsulation module super rust

Rust 支持pubpub(super)pub使得父模块可以访问一个项目......并且pub(super)似乎也做了完全相同的事情。我尝试过使用下面的示例,并进行交换pubpub(super)似乎没有效果:

#![allow(dead_code)]

mod outer {
    pub(super) fn outer_foo() { inner::inner_foo(); }
    mod inner {
        pub(super) fn inner_foo() { println!("hello world!"); }
    }
}

fn top_level_foo() { outer::outer_foo(); }
Run Code Online (Sandbox Code Playgroud)

为什么你会使用其中一种而不是另一种?

游乐场链接。

Ren*_*ato 3

在您的示例中,如果您将inner模块更改为公开,那么差异就会变得很明显。

例如,这是有效的,因为outer::inner::inner_foo从主模块可见:

#![allow(dead_code)]

mod outer {
    pub(super) fn outer_foo() { inner::inner_foo(); }
    pub mod inner {
        pub fn inner_foo() { println!("hello world!"); }
    }
}

fn top_level_foo() { outer::outer_foo(); }

fn main() {
    outer::inner::inner_foo();
}
Run Code Online (Sandbox Code Playgroud)

如果你保留它inner_foo,因为pub(super)它只能从模块中可见outer(因为super指的是超级模块,outer在内部有东西的情况下inner),因此上面的代码将无法编译,你会看到这个错误:

   |
13 |     outer::inner::inner_foo();
   |                   ^^^^^^^^^ private function
   |
note: the function `inner_foo` is defined here
Run Code Online (Sandbox Code Playgroud)

请注意,pub也可以将其crate作为参数,使该函数在 crate 本身内公开,但不对其他 crate 公开。

  • 我总结一下,“pub(thing)”的意思是“让封闭模块可以访问它,但不要让它通过封闭“thing”之外的模块来重新公开”。因此,它就像公共一样,对于可以再出口的程度有一个上限。 (3认同)