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
相关产品推荐
相关产品推荐

