为什么当一个结构体在不同的模块中时,Rust不能访问私有字段?

bhmjp9jg  于 2023-03-08  发布在  其他
关注(0)|答案(1)|浏览(242)
constructors
    |---------src
    |          |----------lib.rs
    |          |----------constructor_file.rs    
    |
    |----------Cargo.toml
    |----------main.rs
    • 库文件**
pub mod 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);
    }
}
    • 主文件. 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();
}
    • 货物运输工具**
[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>

为什么当我把Personmain.rs保存在同一个文件中时,这个错误没有出现?

    • 主文件. 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();
}
aurhwmvo

aurhwmvo1#

因为...
如果一个项目是私有的,它可以被当前模块及其后代访问。
如果结构是在main.rs中定义的,那么main.rs是“模块或其后代”的一部分,因此私有字段是可访问的。
如果该结构是在子模块中定义的,那么main.rs * 不是 *“该模块或其后代”的一部分,并且私有字段是不可访问的。
正如本书中所述,与许多其他语言不同,由于Rust的隐私基线非常严格,因此您在定义可见性时比定义“公共”要灵活得多。
值得注意的是,您可以将符号定义为pub(super)以使其可以从父模块访问,而将其定义为pub(crate)以使其可以从整个crate访问。
在许多语言(例如java)中,默认值是pub(crate),必须选择“private”。在Rust中,情况正好相反,“private”是默认值(尽管我认为它比Java自己的private更宽松一些)。

相关问题