Menu
CoddyTech

public 关键字

本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 9 课,共 61 课。

在上一课中,你学习了如何将代码整理到单独的模块文件中。不过,如果你尝试在 main.rs 中使用 Player 结构体,就会遇到编译器错误。这是因为 Rust 模块中的所有内容默认都是私有的。

要让模块外部也能访问这些项,你必须显式地用 pub 关键字标记它们:

// player.rs
pub struct Player {
    pub name: String,
    pub score: u32,
}

impl Player {
    pub fn new(name: String) -> Player {
        Player { name, score: 0 }
    }
}

注意,pub 出现在多个位置:结构体本身、每个字段以及方法上。每一项都需要单独声明可见性。

如果结构体上没有 pub,其他文件甚至无法引用这个类型。如果字段上没有 pub,其他文件就无法直接访问数据。如果方法上没有 pub,其他文件就无法调用这些方法。

现在,在 main.rs 中,你可以使用模块的公开项:

// main.rs
mod player;

use player::Player;

fn main() {
    let p = Player::new(String::from("Alice"));
    println!("{}", p.name);
}

use 语句将 Player 引入作用域,这样你就不必每次都写 player::Player。这种默认隐私的设计是有意为之的。它鼓励你仔细考虑代码中哪些部分应该暴露给外部。

challenge icon

挑战

简单

我们来通过将代码分到两个文件中,并将合适的项目设为公开,构建一个简单的产品目录,这样主程序就能使用它们。

你需要创建两个文件:

  • product.rs:定义一个包含两个字段的 Product 结构体:name(String)和 price(f64)。添加一个名为 new 的关联函数,它接收名称和价格,并返回一个新的 Product。记得将结构体、它的字段和方法都标记为公开,这样才能从模块外部访问它们。
  • main.rs:声明 product 模块,通过 use 语句将 Product 引入作用域,然后创建一个产品并打印它的详细信息。

仔细考虑哪些地方需要使用 pub 关键字:结构体本身需要可见,字段需要可供读取,构造方法需要能从 main.rs 中调用。

你的输出应遵循以下格式:

Product: {name}, Price: ${price}

例如,如果你创建的产品名称是 "Laptop",价格是 999.99,输出将是:

Product: Laptop, Price: $999.99

你会收到两个输入:产品名称和价格。

亲手试试

// 声明 product 模块
mod product;

// TODO: 用 use 语句将 Product 引入作用域

fn main() {
    // 读取输入
    let mut name = String::new();
    std::io::stdin().read_line(&mut name).expect("Failed to read line");
    let name = name.trim().to_string();
    
    let mut price_input = String::new();
    std::io::stdin().read_line(&mut price_input).expect("Failed to read line");
    let price: f64 = price_input.trim().parse().expect("Failed to parse price");
    
    // TODO: 用 Product::new 函数创建一个新的 Product
    
    // TODO: 按以下格式输出产品详情:
    // Product: {name}, Price: ${price}
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Rust 在线编译器