DAILY DOCDAILY DOC
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
  • rust

    • Rust
    • add
    • 属性(attributes)
    • cargo issue
    • cli
    • build.rs
    • Enums
    • eventEmitter(rust)
    • 格式化输出 std::fmt
    • rust iterator
    • rust 学习计划
    • 生命周期(lifetime)
    • Linked List
    • log
    • macros
    • mem::size_of
    • niche optimization
    • Rust 所有权
    • 模式匹配(pattern matching)
    • module system
    • result & option
    • .rust-analyzer.json
    • rust startup
    • rust-test
    • 可见性(visibility)
    • cargo
    • toml

可见性(visibility)

1. 默认可见性

默认情况下,Rust 中的所有项(函数、类型、模块等)都是私有的(private),即它们只能在定义它们的模块内部访问。这可以有效地避免意外的 API 暴露,强制用户使用模块提供的公共接口。

details
mod Math {
    const LEN: usize = 1;
    static capacity: usize = 1;

    fn add(a: usize, b: usize) -> usize {
        a + b
    }
    fn add_and_log(a: usize, b: usize) -> () {
        println!("result is {}", add(a, b) + LEN + capacity);
    }
}

2. pub 关键字

pub 关键字用于显式地将项标记为公共的(public),使其可以被其他模块访问。在 Rust 中,有几种使用方式:

  • 模块级别的 pub: 用于标记整个模块及其内容对外部的可见性。

    // src/lib.rs
    pub mod my_module {
        pub fn public_function() {
            // 公共函数
        }
    
        fn private_function() {
            // 私有函数
        }
    }
    
  • 结构体、枚举和 trait 的 pub: 用于标记结构体、枚举和 trait 可以在其他模块中使用。

    pub struct PublicStruct {
        // 公共结构体
    }
    
    impl PublicStruct {
        pub fn new() -> Self {
            // 公共方法
            PublicStruct {}
        }
    }
    
  • 函数级别的 pub: 用于标记函数可以在其他模块中调用。

    pub fn public_function() {
        // 公共函数
    }
    

3. pub(crate) 和 pub(in path)

除了全局的 pub,Rust 还支持限制可见性到模块本身或其父级模块(pub(crate)),或者限制到特定的路径(pub(in path))。

  • pub(crate): 限制可见性到当前 crate 内部。

    mod my_module {
        pub(crate) fn internal_function() {
            // 只在当前 crate 内部可见的函数
        }
    }
    
  • pub(in path): 限制可见性到指定路径中的模块。

使用 pub(in path) 语法定义的函数只在给定的路径中可见。 path 必须是父模块(parent module)或祖先模块(ancestor module)

仅限在同一个crate 中

  mod outer {
      pub mod inner {
          pub(in crate::outer) fn restricted_function() {
              // 只在 crate::outer 模块内可见的函数
          }
      }
  }

4. pub use 重导出

pub use 允许将一个项重新导出到当前模块的公共接口,这在创建模块的公共 API 时非常有用。

mod private_module {
    pub fn internal_function() {
        // 内部函数
    }
}

pub mod public_module {
    pub use private_module::internal_function;

    pub fn public_function() {
        // 公共函数
    }
}

7. pub(crate) 的详细使用

pub(crate) 是 Rust 中一种特殊的可见性修饰符,用于限制项(函数、类型、模块等)只在当前 crate 内部可见。这种限制非常有用,特别是在需要隐藏特定实现细节但又需要模块内部共享的情况下。

7.1. 在模块中使用 pub(crate)

在模块中使用 pub(crate) 可以确保其内部的项只能在当前 crate 中的其他模块中使用,而不会暴露给外部 crate。

// src/lib.rs
pub mod my_module {
    pub(crate) fn internal_function() {
        // 只在当前 crate 内部可见的函数
    }
}

// 在其他模块中使用
mod another_module {
    use crate::my_module::internal_function;

    pub fn call_internal_function() {
        internal_function();
    }
}

7.2. pub(crate) 和 pub 的比较

  • pub: 公共的,可以被当前 crate 内外的所有模块访问。
  • pub(crate): 只有当前 crate 内部的所有模块可以访问,外部 crate 禁止访问。

通过使用 pub(crate),你可以在保持模块私有性的同时,允许 crate 内部的不同模块共享实现细节,这对于确保代码的内聚性和封装性非常重要。

7.3. pub(crate) 示例

// src/lib.rs
pub mod data {
    pub(crate) struct Database {
        // 数据库结构体,只有当前 crate 内部可见
    }

    impl Database {
        pub(crate) fn new() -> Self {
            // 创建数据库实例,只有当前 crate 内部可见
            Database {}
        }

        pub fn query(&self, query: &str) {
            // 查询方法,可以在当前 crate 内外的所有模块中使用
        }
    }
}

// 在其他模块中使用
mod services {
    use crate::data::Database;

    pub fn perform_query() {
        let db = Database::new();
        db.query("SELECT * FROM users");
    }
}

在上面的示例中,Database 结构体和其 new 方法使用了 pub(crate),这意味着只有定义了 Database 的 crate 内部的所有模块可以创建 Database 实例和调用 new 方法,而 query 方法由于是 pub,所以可以在当前 crate 内外的所有模块中使用。

Last Updated:
Contributors: rosendo
Prev
rust-test
Next
cargo