404 Not Found

404 Not Found


nginx

RustのモジュールシステムとCargo:コードの整理とプロジェクト管理

モジュールシステムは、Rustの「コードのアドレス指定方式」です。建物の住所と同じように、これにより、コードの各部分の場所を正確に特定し、外部からどの部分にアクセスできるかを制御することができます。

もし大規模なプロジェクトを都市に例えるなら、モジュール(mods)は地区、ファイルは建物、関数は部屋に相当するでしょう。Cargoは都市の行政機関のようなもので、道路の建設、維持管理、品質の確保を担当しています。モジュールシステムがなければ、コードは「集落」がごちゃ混ぜになったような状態になってしまうでしょう。


1. 学習内容


2. マンションの部屋番号付けの仕組みにまつわるエピソード

(1) 苦難:家番号のない街

トムは新築のマンションに引っ越したが、そこには家番号の付け方がないことに気づいた。

「建物・ユニット・アパートというように、標準化された家屋番号の付け方があれば素晴らしいのですが……」

(2) Rustのモジュールシステムへのアプローチ

TEXT
Apartment(Crate)           → A building
  Building Name(crate name)   → Building Number
  Unit(Module)         → Apartment Building Entrance
    Room Number(Function)   → Specific Rooms
RUST
// File Structure Correspondence:
// src/
//   main.rs              → Apartment Lobby(Entrance)
//   building/
//     mod.rs             → Building Information
//     unit_1/
//       mod.rs           → 1 Unit
//       room_501.rs      → 501 Room
//       room_502.rs      → 502 Room

// In Rust, through mod and pub, precisely control who can access what
mod building {
    pub mod unit_1 {
        pub fn room_501() -> &'static str {
            "501 Room: Tom Home"
        }

        fn room_502() -> &'static str {
            "502 Room: Private Space"  // Default: Private, not visible externally
        }
    }
}

fn main() {
    // Access via the full path
    println!("{}", building::unit_1::room_501());
    // println!("{}", building::unit_1::room_502());  // ❌ Private Functions,Compilation Error
}

Rustのモジュールシステムは、マンションの住所体系のようなものです。crateは建物全体を表し、modは棟を表し、fnは各住戸を表します。pubは、どの住戸に外へ通じるドアがあるかを制御します。pubがない住戸はプライベートな空間であり、部外者は自由に出入りできません。


3. 基本概念

(1) モジュールシステムとパス

100%
graph TB
    A[Rust Modular System] --> B[mod Definition]
    A --> C[pub Visibility]
    A --> D[use Path Import]
    A --> E[Cargo Project Management]

    B --> B1["mod Module Name { ... }"]
    B --> B2["mod Module Name;  // From a file"]

    C --> C1["pub: Visible to the public"]
    C --> C2["pub(crate): crate only, visible inside"]
    C --> C3["pub(super): Visible only to the parent module"]
    C --> C4["No pub: Private"]

    D --> D1["use crate::a::b::c;"]
    D --> D2["use super::module;"]
    D --> D3["use self::module;"]

    E --> E1["Cargo.toml Dependency"]
    E --> E2["cargo build / test"]
    E --> E3["workspace Multiple Packages"]
    E --> E4["lib.rs vs main.rs"]

(2) 可視性ルールの比較

公開範囲 キーワード アクセス権限 類似例
非公開 なし(デフォルト) 現在のモジュールおよびサブモジュール 寝室に入ることができるのは家族のみ
親モジュールから表示可能 pub(super) 親モジュール 上下階の隣人が立ち寄れる
クレート内で表示されるもの pub(crate) 現在のクレート内のすべてのモジュール 居住者はコミュニティのゲートから入ることができます
公開 pub すべての外部クレート 誰でもモールに入ることができる

(3) パスの種類

パス種別 プレフィックス 説明
絶対パス crate:: crate::utils::helper::foo クレートのルートから
相対パス self:: self::helper::foo 現在のモジュールから
相対パス super:: super::helper::foo 親モジュールから
外部パス パッケージ名 serde::Serialize 外部のcrateから開始

(4) 一般的な貨物コマンドのクイックリファレンス

コマンド 機能 一般的なオプション
cargo new 新規プロジェクトの作成 --lib (ライブラリプロジェクト)
cargo build プロジェクトのコンパイル --release (最適化コンパイル)
cargo run コンパイルして実行 --bin name (バイナリを指定)
cargo check コンパイルエラーを素早く確認 ビルドよりも高速;バイナリは生成されない
cargo test テストを実行 test_name (指定されたテスト)
cargo doc ドキュメントを生成 --open (ブラウザが自動的に開きます)
cargo clippy コードのリンティングチェック -W clippy::all
cargo fmt コードの書式設定 --check (確認のみ。変更しないでください)
cargo add 依存関係を追加 --features xxx
cargo update 依存関係ロックファイルを更新 Cargo.lock を更新
cargo publish crates.io に公開 まずログインする必要があります
cargo clean ビルドアーティファクトのクリーンアップ target/ ディレクトリの削除

4. モジュールとCargoの例

(1) ▶ サンプル:モジュールの定義と pub の可視性 (難易度 ⭐)

RUST
// ============================================
// Module Nesting、pub Visibility、Path Access
// Demo: The restaurant's kitchen is not visible to customers, but visible to servers
// ============================================

// Defining the Restaurant Module
mod restaurant {
    // Public: Customers may enter the restaurant
    pub struct Menu {
        pub name: String,
        price: f64,  // Default: Private,Not visible externally
    }

    impl Menu {
        // Public Constructor
        pub fn new(name: &str, price: f64) -> Menu {
            Menu {
                name: name.to_string(),
                price,
            }
        }

        // Public Methods: Get Price
        pub fn get_price(&self) -> f64 {
            self.price
        }
    }

    // Public: Customers can order food
    pub fn order_food(item: &str) -> String {
        // Private: Kitchen operations are not visible to customers
        let prepared = prepare_in_kitchen(item);
        format!("Your {} Ready: {}", item, prepared)
    }

    // Private: Customers are not allowed in the kitchen.
    fn prepare_in_kitchen(item: &str) -> String {
        format!("[Kitchen] {} Cooking in progress...", item)
    }

    // Nested Modules: Inside the Kitchen
    mod kitchen {
        // Private Storage Area
        pub struct Storage {
            pub items: Vec<String>,
        }

        impl Storage {
            pub fn new() -> Storage {
                Storage {
                    items: vec![
                        "Vegetables".to_string(),
                        "Meat".to_string(),
                        "Seasonings".to_string(),
                    ],
                }
            }
        }
    }
}

fn main() {
    // Accessing Public Module Members
    let dish = restaurant::order_food("Kung Pao Chicken");
    println!("{}", dish);

    // Create a public struct
    let menu_item = restaurant::Menu::new("Kung Pao Chicken", 38.0);
    println!("Dishes: {}, Price: {:.1} yuan", menu_item.name, menu_item.get_price());

    // The following code cannot be compiled(Uncomment this line to try it):
    // println!("Chef Information: {}", restaurant::prepare_in_kitchen("Kung Pao Chicken"));  // ❌ Private Functions
    // println!("Price: {}", menu_item.price);  // ❌ Private Fields
    // let storage = restaurant::kitchen::Storage::new();  // ❌ kitchen The module is private.
}

出力:

TEXT
Your Kung Pao Chicken Ready: [Kitchen] Kung Pao Chicken Cooking in progress...
Dishes: Kung Pao Chicken, Price: 38.0 yuan

モジュールの可視性ルールは、レストランの物理的なレイアウトに例えることができます。顧客(外部コード)はダイニングルーム(pub モジュール)にしか入ることができず、厨房(プライベートモジュール)には立ち入ることができません。厨房(prepare_in_kitchen)で行われている作業は、外部からはまったく見えません。これがカプセル化です。


(2) ▶ サンプル:use の経路と super/crate (難易度: ⭐⭐)

RUST
// ============================================
// use Keyword Import Path、super and crate Relative Path
// Simulation: Company Organizational Structure - Department→Group→Employees
// ============================================

// Top-Level Module: Company
mod company {
    // Engineering Department
    pub mod engineering {
        pub fn team_name() -> &'static str {
            "Engineering Department"
        }

        // Front-End Team
        pub mod frontend {
            pub fn member_count() -> u32 {
                5
            }

            // Use super to access the parent module (engineering)
            pub fn full_info() -> String {
                format!("{} Front-End Team, {} people", super::team_name(), member_count())
            }
        }

        // Backend Team
        pub mod backend {
            pub fn member_count() -> u32 {
                8
            }

            // Usage super Access the Parent Module
            pub fn full_info() -> String {
                format!("{} Backend Team, {} people", super::team_name(), member_count())
            }
        }
    }

    // Marketing Department
    pub mod marketing {
        pub fn team_name() -> &'static str {
            "Marketing Department"
        }

        // Usage crate Path Access from the Root
        pub fn total_employees() -> u32 {
            // From crate root, access begins
            crate::company::engineering::frontend::member_count()
            + crate::company::engineering::backend::member_count()
            + self::member_count()
        }

        fn member_count() -> u32 {
            6
        }
    }
}

// Usage use Import Path——Simplify the call
use company::engineering::frontend;
use company::engineering::backend;
use company::marketing;

fn main() {
    // Method 1: Full path (Not recommended, too long to write)
    println!("{}", company::engineering::frontend::full_info());

    // Method 2: Call directly after use import (Recommended)
    println!("{}", frontend::full_info());
    println!("{}", backend::full_info());

    // Introduction marketing Module
    println!("Number of employees in the Marketing Department: {}", marketing::member_count());

    // Usage crate Path Access
    println!("Total Number of Employees: {}", marketing::total_employees());

    // Usage as Avoiding Alias Conflicts
    use company::engineering as eng;
    println!("Department: {}", eng::team_name());
}

出力:

TEXT
Engineering Department Front-End Team, 5 people
Engineering Department Backend Team, 8 people
Number of employees in the Marketing Department: 6
Total Number of Employees: 19
Department: Engineering Department

use これは「家番号」へのショートカットを作成するようなもので、毎回完全な住所を入力する必要がなくなります company::engineering::frontend::full_info()super は「1つ上のレベルへ移動」(親モジュール)を意味し、crate は「建物の入り口に戻る」(ルート)を意味します。as キーワードを使用することで、パスに別名を割り当て、名前の重複による競合を解決することができます。


(3) ▶ サンプル:Cargo.toml における依存関係管理とプロジェクト構造 (難易度: ⭐⭐)

RUST
// ============================================
// Simulation Cargo Project Structure + Dependency Management
// Demo:lib.rs and main.rs Division of Labor、Using External Dependencies
// ============================================

// Note: This example demonstrates the code in lib.rs
// Actual Cargo.toml See the note below for the contents of the document.

// ============================================
// Cargo.toml Content (Simulation):
// ============================================
// [package]
// name = "my-toolkit"
// version = "0.1.0"
// edition = "2021"
//
// [dependencies]
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
// chrono = "0.4"
// regex = "1.10"
//
// [dev-dependencies]
// rand = "0.8"
//
// [profile.release]
// opt-level = 3
// ============================================

// Tools Module: Date Handling
pub mod date_utils {
    pub fn format_today() -> String {
        // Used in actual projects chrono::Local::now()
        "2026-07-03".to_string()
    }

    pub fn is_weekend(day: &str) -> bool {
        day.ends_with("Saturday") || day.ends_with("Sunday")
    }
}

// Tools Module: String Processing
pub mod string_utils {
    /// Verify the email address format (Simulating Regular Expression Matching)
    pub fn validate_email(email: &str) -> bool {
        // Simplified Verification: Use regex crate in practice
        email.contains('@') && email.contains('.')
    }

    /// Remove non-alphanumeric characters (Simulation)
    pub fn sanitize(input: &str) -> String {
        input.chars()
            .filter(|c| c.is_alphanumeric() || *c == ' ')
            .collect()
    }
}

// Tools Module: Mathematical Calculations
pub mod math_utils {
    /// Calculate the nth term of the nth term of the Fibonacci sequence
    pub fn fibonacci(n: u32) -> u64 {
        match n {
            0 => 0,
            1 => 1,
            _ => fibonacci(n - 1) + fibonacci(n - 2),
        }
    }

    /// Determining Whether a Number Is Prime
    pub fn is_prime(n: u32) -> bool {
        if n < 2 {
            return false;
        }
        let limit = (n as f64).sqrt() as u32;
        for i in 2..=limit {
            if n % i == 0 {
                return false;
            }
        }
        true
    }
}

// Test Module (Using #[cfg(test)] Conditional Compilation)
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_validate_email() {
        assert!(string_utils::validate_email("user@example.com"));
        assert!(!string_utils::validate_email("invalid"));
    }

    #[test]
    fn test_fibonacci() {
        assert_eq!(math_utils::fibonacci(0), 0);
        assert_eq!(math_utils::fibonacci(1), 1);
        assert_eq!(math_utils::fibonacci(10), 55);
    }

    #[test]
    fn test_is_prime() {
        assert!(math_utils::is_prime(17));
        assert!(!math_utils::is_prime(1));
        assert!(!math_utils::is_prime(4));
    }

    #[test]
    fn test_sanitize() {
        assert_eq!(string_utils::sanitize("hello@world!"), "hello world");
    }
}

// ============================================
// main.rs The code in (Simulation):
// ============================================
// use my_toolkit::{
//     date_utils,
//     string_utils,
//     math_utils,
// };
//
// fn main() {
//     println!("Today's Date: {}", date_utils::format_today());
//     println!("Email Verification: {}", string_utils::validate_email("test@example.com"));
//     println!("Prime Number Check: {}", math_utils::is_prime(17));
// }

fn main() {
    // Demonstration of Each Tool's Functions
    println!("=== Tool Library Demo ===");

    // Date Tools
    println!("Today: {}", date_utils::format_today());
    println!("Is it the weekend?: {}", date_utils::is_weekend("Saturday"));

    // String Tools
    println!("Email Verification test@example.com: {}", string_utils::validate_email("test@example.com"));
    println!("Email Verification invalid: {}", string_utils::validate_email("invalid"));
    println!("Purification 'hello@world!': {}", string_utils::sanitize("hello@world!"));

    // Mathematical Tools
    println!("Fibonacci #10: {}", math_utils::fibonacci(10));
    println!("17 Is it a prime number?: {}", math_utils::is_prime(17));
    println!("4 Is it a prime number?: {}", math_utils::is_prime(4));

    println!("=== End of Presentation ===");

    // Instructions for Running the Test (Use cargo test in actual projects)
    println!("Usage `cargo test` Run Unit Tests");
}

出力:

TEXT
=== Tool Library Demo ===
Today: 2026-07-03
Is it the weekend?: true
Email Verification test@example.com: true
Email Verification invalid: false
Purification 'hello@world!': hello world
Fibonacci #10: 55
17 Is it a prime number?: true
4 Is it a prime number?: false
=== End of Presentation ===
Usage `cargo test` Run Unit Tests

実際のプロジェクトにおける標準的な構成:lib.rs にはライブラリコード(パブリック API)が含まれ、main.rs には実行可能ファイルのエントリポイント(ライブラリを使用するもの)が含まれます。Cargo.tomlは依存関係を管理し、[dependencies]には本番環境の依存関係が、[dev-dependencies]にはテスト/ビルドツールの依存関係が含まれます。cargo testは、#[test]でマークされた関数を自動的に検出して実行します。


(4) ▶ サンプル:よく使われるカーゴコマンドとワークスペース(難易度 ⭐⭐⭐)

RUST
// ============================================
// Cargo Common Commands and workspace Multi-Package Management
// Simulation: One "Task Manager" workspace Project
// ============================================

// ============================================
// Top Floor Cargo.toml (workspace):
// ============================================
// [workspace]
// members = [
//     "task-core",       // Core Library
//     "task-cli",        // CLI Tools
//     "task-web",        // Web Interface
// ]
//
// [workspace.package]
// version = "1.0.0"
// edition = "2021"
// ============================================

// ============================================
// task-core/Cargo.toml:
// ============================================
// [package]
// name = "task-core"
// version.workspace = true
// edition.workspace = true
//
// [dependencies]
// serde = { version = "1.0", features = ["derive"] }
// chrono = "0.4"
// ============================================

// Simulation task-core Library code
pub mod task_core {
    use std::collections::HashMap;

    /// Task Priority
    #[derive(Debug, Clone, PartialEq)]
    pub enum Priority {
        Low,
        Medium,
        High,
        Urgent,
    }

    /// Task Status
    #[derive(Debug, Clone, PartialEq)]
    pub enum Status {
        Todo,
        InProgress,
        Done,
        Cancelled,
    }

    /// Core Task Structure
    #[derive(Debug, Clone)]
    pub struct Task {
        pub id: u64,
        pub title: String,
        pub priority: Priority,
        pub status: Status,
        pub tags: Vec<String>,
    }

    impl Task {
        pub fn new(id: u64, title: &str, priority: Priority) -> Task {
            Task {
                id,
                title: title.to_string(),
                priority,
                status: Status::Todo,
                tags: Vec::new(),
            }
        }

        pub fn add_tag(&mut self, tag: &str) {
            self.tags.push(tag.to_string());
        }

        pub fn is_completed(&self) -> bool {
            self.status == Status::Done || self.status == Status::Cancelled
        }
    }

    /// Task Manager
    pub struct TaskManager {
        tasks: HashMap<u64, Task>,
        next_id: u64,
    }

    impl TaskManager {
        pub fn new() -> TaskManager {
            TaskManager {
                tasks: HashMap::new(),
                next_id: 1,
            }
        }

        pub fn create_task(&mut self, title: &str, priority: Priority) -> u64 {
            let id = self.next_id;
            self.next_id += 1;
            let task = Task::new(id, title, priority);
            self.tasks.insert(id, task);
            id
        }

        pub fn get_task(&self, id: u64) -> Option<&Task> {
            self.tasks.get(&id)
        }

        pub fn complete_task(&mut self, id: u64) -> bool {
            if let Some(task) = self.tasks.get_mut(&id) {
                task.status = Status::Done;
                true
            } else {
                false
            }
        }

        pub fn list_tasks(&self) -> Vec<&Task> {
            let mut tasks: Vec<&Task> = self.tasks.values().collect();
            tasks.sort_by_key(|t| t.id);
            tasks
        }
    }
}

// ============================================
// Cargo Command Reference (Demonstrated in the comments):
// ============================================
// Common Commands:
//   cargo new project_name      -- Create a New Project
//   cargo build                 -- Compilation (debug)
//   cargo build --release       -- Compilation (release optimization)
//   cargo run                   -- Compilation + Run
//   cargo check                 -- Quickly Check for Compilation Errors (No binary files generated)
//   cargo test                  -- Run Test
//   cargo test test_name        -- Run the specified test
//   cargo bench                 -- Run Performance Benchmarks
//   cargo doc --open            -- Generate the document and open it
//   cargo clippy                -- Code lint Inspection
//   cargo fmt                   -- Code Formatting
//   cargo add crate_name        -- Add Dependencies
//   cargo update                -- Update Dependencies
//   cargo publish               -- Post to crates.io
//   cargo clean                 -- Clean up compilation output
//
// Workspace Commands:
//   cargo build --workspace     -- Compilation workspace All packages in
//   cargo test -p task-core     -- Test only the specified package
//   cargo run -p task-cli       -- Run the specified package

fn main() {
    use task_core::{Priority, TaskManager};

    println!("=== Task Manager (Simulation Workspace Project) ===");

    let mut manager = TaskManager::new();

    // Create a Task
    let id1 = manager.create_task("Study Rust Smart Pointers", Priority::High);
    let id2 = manager.create_task("Complete the module system exercises", Priority::Medium);
    let id3 = manager.create_task("Restore the Production Environment Bug", Priority::Urgent);

    // List all tasks
    println!("\n--- All Tasks ---");
    for task in manager.list_tasks() {
        println!("#{} [{:?}] {} - {:?}", task.id, task.priority, task.title, task.status);
    }

    // Complete a task
    manager.complete_task(id1);
    println!("\nDone #{} after:", id1);
    for task in manager.list_tasks() {
        let status = if task.is_completed() { "Completed" } else { "In progress" };
        println!("#{} {} - {}", task.id, task.title, status);
    }

    // Get a Single Task
    if let Some(task) = manager.get_task(id3) {
        println!("\nUrgent Task: #{} {} ({:?})", task.id, task.title, task.priority);
    }

    println!("\n=== End of Presentation ===");
    println!("Project Structure: task-core (Library) + task-cli (CLI) + task-web (Web)");
    println!("Usage `cargo test -p task-core` Testing the Core Library");
    println!("Usage `cargo doc --open` Generate Document");
}

出力:

TEXT
=== Task Manager (Simulation Workspace Project) ===

--- All Tasks ---
#1 [High] Study Rust Smart Pointers - Todo
#2 [Medium] Complete the module system exercises - Todo
#3 [Urgent] Restore the Production Environment Bug - Todo

Done #1 after:
#1 Study Rust Smart Pointers - Completed
#2 Complete the module system exercises - In progress
#3 Restore the Production Environment Bug - In progress

Urgent Task: #3 Restore the Production Environment Bug (Urgent)

=== End of Presentation ===
Project Structure: task-core (Library) + task-cli (CLI) + task-web (Web)
Usage `cargo test -p task-core` Testing the Core Library
Usage `cargo doc --open` Generate Document

Workspaceは、複数のパッケージからなるプロジェクトを管理するための強力なツールです。task-coreはコアとなる型とロジック(ライブラリ)を提供し、task-cliはコマンドラインインターフェース(実行ファイル)を提供し、task-webはWeb API(別の実行ファイル)を提供し、cargo build --workspaceはすべてのパッケージを一度にコンパイルします。cargo test -p task-coreは、コアライブラリのみをテストします。


(5) ▶ サンプル:総合演習—モジュール設計のシミュレーション(難易度 ⭐⭐⭐)

RUST
// ============================================
// Comprehensive Example: Module Visibility and API Design
// Simulating a Multi-File Project Structure (Actual projects should be broken down into separate files.)
// ============================================

mod math_utils {
    pub fn add(a: i32, b: i32) -> i32 { a + b }
    pub fn multiply(a: i32, b: i32) -> i32 { a * b }
    fn internal_check(val: i32) -> bool { val >= 0 }

    pub fn safe_divide(a: i32, b: i32) -> Option<i32> {
        if b == 0 { return None; }
        if !internal_check(a) || !internal_check(b) { return None; }
        Some(a / b)
    }

    pub mod constants {
        pub const PI: f64 = 3.14159265358979;
        pub const E: f64 = 2.71828182845905;
        pub const MAX_I32: i32 = i32::MAX;
    }
}

mod string_utils {
    pub fn capitalize(s: &str) -> String {
        let mut chars = s.chars();
        match chars.next() {
            None => String::new(),
            Some(first) => first.to_uppercase().collect::<String>() + chars.as_str(),
        }
    }

    pub fn truncate(s: &str, max_len: usize) -> String {
        if s.len() <= max_len { s.to_string() }
        else { format!("{}...", &s[..max_len.min(s.len())]) }
    }
}

mod user {
    pub struct User {
        pub name: String,
        age: u8,
        email: String,
    }

    impl User {
        pub fn new(name: &str, age: u8, email: &str) -> Self {
            User { name: name.to_string(), age, email: email.to_string() }
        }

        pub fn age(&self) -> u8 { self.age }

        pub fn summary(&self) -> String {
            format!("{} ({} years old, {})", self.name, self.age, self.email)
        }
    }
}

fn main() {
    use math_utils::{add, multiply, safe_divide, constants};
    use string_utils::{capitalize, truncate};
    use user::User;

    println!("=== math_utils Module ===");
    println!("2 + 3 = {}", add(2, 3));
    println!("4 * 5 = {}", multiply(4, 5));
    println!("10 / 3 = {:?}", safe_divide(10, 3));
    println!("10 / 0 = {:?}", safe_divide(10, 0));
    println!("PI = {:.5}, E = {:.5}", constants::PI, constants::E);

    println!("\n=== string_utils Module ===");
    println!("capitalize: '{}'", capitalize("rust"));
    println!("truncate: '{}'", truncate("Hello, World!", 8));

    println!("\n=== user Module ===");
    let alice = User::new("Alice", 30, "alice@example.com");
    println!("{}", alice.summary());
    println!("Age: {}", alice.age());
}

出力:

TEXT
=== math_utils Module ===
2 + 3 = 5
4 * 5 = 20
10 / 3 = Some(3)
10 / 0 = None
PI = 3.14159, E = 2.71828

=== string_utils Module ===
capitalize: 'Rust'
truncate: 'Hello, ...'

=== user Module ===
Alice (30 years old, alice@example.com)
Age: 30

モジュール設計の3つの原則:pub 必要なAPI(addsafe_divide など)のみを公開し、内部の詳細(internal_check など)は非公開にする; サブモジュール(constantsなど)はpub modを介して公開される。構造体のフィールドには、個別に可視性(private pub name / age + age() ゲッター)が注釈として付される。


❓ よくある質問

Q modfn の違いは何ですか?ファイルを使って整理しないのはなぜですか?
A mod はモジュール定義であり、fn は関数定義です。
Q pub(crate)pub の違いは何ですか?
A pub(crate) は同じクレート内のコードからのみ参照可能ですが、pub はすべての外部クレートから参照可能です。
Q use super::xxxuse crate::xxx はいつ使用すべきですか?
A super は親モジュールへのアクセス(相対パス)に使用され、crate はクレートのルートから始まるコンテンツへのアクセス(絶対パス)に使用されます。
Q Cargo.toml にあるバージョン番号 ^1.2.3 はどういう意味ですか?
A ^ は「互換性アップデート」を表しており、このバージョンでは >=1.2.3 および <2.0.0 が利用可能です。
Q lib.rsmain.rs は共存できますか?
A はい。

📖 まとめ


📝 練習問題

  1. 難易度 ⭐mathgreeting の 2 つのモジュールを含むプログラムを作成してください。math モジュールにはパブリック関数 add(a: i32, b: i32) -> i32 が、greeting モジュールにはパブリック関数 say_hello(name: &str) -> String があります。main内で、これら2つの関数を呼び出してください。
  2. 難易度 ⭐⭐:「ライブラリ」モジュールシステムをシミュレートします。library モジュールを作成し、その中に books サブモジュール(書籍管理)と members サブモジュール(会員管理)を含めます。booksにはadd_bookおよびlist_books関数が、membersにはadd_memberおよびlist_members関数が含まれています。pub(super) および pub(crate) を使用して、表示設定を適切に制御してください。main モジュールでは、書籍や会員の追加方法を示しています。
  3. 難易度 ⭐⭐⭐: Cargo ワークスペースのプロジェクト構造を確認します。core-libaddおよびsubtract関数を提供するライブラリ)とcli-appcore-libを使用して計算を行い、結果を出力する実行ファイル)を含むワークスペースプロジェクトをローカルに作成します。Cargo.tomlのワークスペース設定を行い、cargo build --workspaceを使用してコンパイルし、cargo run -p cli-appを使用して実行します。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%