公共模块在一个或多个函数需要对外公开才能发挥作用时有什么用途?

huangapple go评论59阅读模式
英文:

What purpose does a public module serve when one or more functions need to be public for this to have any effect?

问题

In Rust, pub in front of a module declaration serves to make the module itself public, allowing other modules to use its contents. All members of a module are private by default, so if you want a specific entity (like a function) within the module to be accessible from outside, you must declare it as public using pub as well. Therefore, the scope (public or private) of a module is not redundant; it determines the visibility of the module and its members.

Reference: https://doc.rust-lang.org/book/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html

英文:

What purpose does pub in front of a module declaration in Rust serve?

All the members of a module are private by default, irrespective of whether a module is public or private (the default).

In order for a member of a module to be public, that entity (function, etc) must be declared public using pub also.

Hence it appears that the scope (public or private) of a module is redundant. Is this the case?

Reference: https://doc.rust-lang.org/book/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html

答案1

得分: 2

这个问题对于那些主要编写应用程序的人来说是完全有道理的。差别不大。

但我以编写库为生(不幸的是不是用Rust,但相同的考虑因素适用),所以差别对我来说非常重要。

假设我有一个叫做Foo的crate,它有两个模块,分别命名为BarBaz,每个模块都有一个公共函数f和一个私有函数g,但Baz是私有的:

pub mod Bar {
  pub fn f() -> () {}
  fn g() -> () {}
}

mod Baz {
  pub fn f() -> () {}
  fn g() -> () {}
}

所以在这个设置中:

  • Bar::gBaz::g局限于它们各自的模块,我不能在主函数中调用它们。
  • Bar::fBaz::f在它们的模块中是公共的,我可以在主函数中调用它们。
  • Bar::f对于我的crate的使用者是公共的API的一部分,他们可以调用Foo::Bar::f,但关键是不能调用Foo::Baz::f

最后一部分是重要的,如果你不经常为其他开发人员编写库(甚至是为自己在多个项目中使用的库)工作,很容易忽视这个区别。

英文:

This question makes perfect sense if it's coming from someone who mostly writes applications. There isn't much difference.

But I write libraries for a living (not in Rust unfortunately, but the same considerations apply), so the difference matters a lot to me.

Let's say I have a crate Foo and it has two modules, creatively named Bar and Baz, and each one has public function f and private function g but Baz is private:

pub mod Bar {
  pub fn f() -> () {}
  fn g() -> () {}
}

mod Baz {
  pub fn f() -> () {}
  fn g() -> () {}
}

So in this setup:

  • Bar::g and Baz::g are local to their respective modules, I can't e.g. call them in main.
  • Bar::f and Baz::f are public in their modules, I can e.g. call them from main.
  • Bar::f is public to consumers of my crate (i.e. is part of my public API), they can call Foo::Bar::f, but crucially not Foo::Baz::f.

That last bit is the important part, and if you don't regularly work on libraries intended for other developers (or even intended for yourself to use in multiple projects) it's an easy distinction to miss.

答案2

得分: 0

这允许您拥有细粒度的封装 作用域。考虑以下示例。

pub mod A {
    mod B {
        pub fn foo() {
            println!("foo");
        }
    }
    
    pub fn bar() {
        println!("calling foo");
        B::foo()
    }
}

fn main() {
    A::bar();
    
    // A::B is private. Can't call foo
    // A::B::foo();
}

您有一个公共模块 A,在其中有一个带有辅助函数的私有模块 BA 中的函数可以调用 B 中的函数,但在 A 外部的调用者不能调用其辅助函数。

英文:

This allows you to have a fine-grained scopes of encapsulation. Consider the following example.

pub mod A {
    mod B {
        pub fn foo() {
            println!("foo");
        }
    }
    
    pub fn bar() {
        println!("calling foo");
        B::foo()
    }
}

fn main() {
    A::bar();
    
    // A::B is private. Can't call foo
    // A::B::foo();
}

You have a public module A and inside of it you have a private module B with helper functions. Functions in A can call functions from B, but callers outside of A cannot call its helper functions.

huangapple
  • 本文由 发表于 2023年5月10日 18:59:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217598.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定