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

Rust跨模块无法访问结构体私有字段,同文件无错误原因解析

为什么拆分结构体到库模块后会出现私有字段错误?

项目结构

constructors
    |---------src
    |          |----------lib.rs
    |          |----------constructor_file.rs    
    |
    |----------Cargo.toml
    |----------main.rs

lib.rs

pub mod constructor_file;

constructor_file.rs

pub struct Person {
    name: String,
    age: u32,
}

impl Person {
    pub fn new(name: String, age: u32) -> Person {
        Person { name, age }
    }
    pub fn show(self)
    {
        println!("Name: {}, Age: {}", self.name, self.age);
    }
}

main.rs

use constructor_lib::constructor_file::Person;

fn main() {
    let person = Person { name: "Alice".to_string(), age: 33 };
    person.show();
    let person2 = Person::new("Bob".to_string(), 99 );
    person2.show();
}

Cargo.toml

[package]
name = "constructor_lib"
version = "0.1.0"
edition = "2021"

[[bin]]
name="constructor_exe"
path="main.rs"

编译错误信息

C:\git\Rust examples\constructors>cargo build
   Compiling constructor_lib v0.1.0 (C:\git\Rust examples\constructors)
error[E0451]: field `name` of struct `Person` is private
 --> main.rs:4:27
  |
4 |     let person = Person { name: "Alice".to_string(), age: 33 };
  |                           ^^^^^^^^^^^^^^^^^^^^^^^^^ private field

error[E0451]: field `age` of struct `Person` is private
 --> main.rs:4:54
  |
4 |     let person = Person { name: "Alice".to_string(), age: 33 };
  |                                                      ^^^^^^^ private field

For more information about this error, try `rustc --explain E0451`.
error: could not compile `constructor_lib` due to 2 previous errors

C:\git\Rust examples\constructors>

无错误的单文件版本(main.rs)

//use constructor_lib::constructor_file::Person;
pub struct Person {
    name: String,
    age: u32,
}

impl Person {
    pub fn new(name: String, age: u32) -> Person {
        Person { name, age }
    }
    pub fn show(self)
    {
        println!("Name: {}, Age: {}", self.name, self.age);
    }
}

fn main() {
    let person = Person { name: "Alice".to_string(), age: 33 };
    person.show();
    let person2 = Person::new("Bob".to_string(), 99 );
    person2.show();
}

原因解释

这是Rust可见性规则导致的:

  • 当Person结构体和main函数在同一文件时,它们属于同一个 crate 的根模块。在同一模块内,即使结构体字段没有加pub修饰,模块内的代码也能直接访问这些私有字段,所以可以直接用结构体字面量Person { ... }创建实例。
  • 拆分到库模块后,main.rs属于二进制 crate,而Person结构体定义在库 crate(constructor_lib)的子模块中。此时,虽然结构体本身被标记为pub可以被外部访问,但它的字段默认是私有(没有pub修饰),外部 crate 的代码无法直接访问这些私有字段,也就不能用结构体字面量直接构造实例,只能通过结构体提供的pub方法(比如new)来创建实例。

如果想让外部能直接用字面量构造Person,需要把结构体的字段也标记为pub:

pub struct Person {
    pub name: String,
    pub age: u32,
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:13:30