You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust隐私规则:如何将结构体移入模块且仅对原模块可见

Rust模块拆分后的可见性控制方案

用精准的可见性修饰符替代全局pub

Rust提供了比单纯pub更灵活的访问控制,既能让父模块访问子模块里的结构体,又能对外隐藏细节,完美适配你拆分长文件的需求。

1. 只让直接父模块访问:pub(super)

如果你的需求仅仅是父模块能访问,其他模块一概不行,给结构体和需要调用的方法加上pub(super)修饰:

// 子模块文件:src/child.rs
pub(super) struct MyStruct {
    data: i32,
}

impl MyStruct {
    pub(super) fn new(data: i32) -> Self {
        MyStruct { data }
    }

    // 父模块要调用的方法也得加pub(super)
    pub(super) fn get_data(&self) -> i32 {
        self.data
    }
}

然后在父模块里直接用就行:

// 父模块文件:src/lib.rs 或 src/main.rs
mod child;

use child::MyStruct;

fn main() {
    let s = MyStruct::new(42);
    println!("{}", s.get_data());
}

这种设置下,除了这个直接父模块,哪怕是同一crate里的其他子模块也碰不到MyStruct,彻底保证封装性。

2. 让整个crate内部都能访问:pub(crate)

如果拆分的多个子模块之间也需要互相访问,但不想对外暴露,就用pub(crate):

// 子模块文件:src/child.rs
pub(crate) struct MyStruct {
    data: i32,
}

impl MyStruct {
    pub(crate) fn new(data: i32) -> Self {
        MyStruct { data }
    }
}

这样整个项目(crate)里的任何模块都能导入使用MyStruct,但当别人把你的crate当依赖用的时候,完全看不到这个结构体。

3. 多子模块的组织技巧:用父模块封装内部细节

如果有一堆相关的子模块需要互相调用,但对外只暴露统一接口,可以把它们都塞进一个私有父模块里:

// src/lib.rs
// 这个父模块默认私有,对外不可见
mod internal {
    pub mod module_a {
        pub(super) struct StructA;
    }

    pub mod module_b {
        use super::module_a::StructA;

        pub fn do_something() {
            let _a = StructA;
            // 这里可以随便用StructA
        }
    }
}

// 对外只暴露需要的公开接口
pub fn public_entry() {
    internal::module_b::do_something();
}

这种方式下,所有内部结构体都只在internal范围内可见,对外完全隐藏,同时代码拆分得清清楚楚。

总结一下

  • 别用全局pub,优先选pub(super)或pub(crate)控制访问范围
  • 拆分模块时,内部细节尽量私有,只对外暴露必要的API
  • Rust的可见性是按作用域来的,精准控制既能拆分代码,又不破坏封装

内容的提问来源于stack exchange,提问作者user2138149

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 00:06:13