关于rust:rust学习引用模块树中项目的路径Paths

为了向Rust展现在模块树中找到我的项目的地位,咱们应用的门路与浏览文件系统时应用的门路雷同。 如果要调用函数,则须要晓得其门路。

门路能够采纳两种模式:
绝对路径从板条箱根开始通过应用一个create名称或一个文字create。
相对路径从以后模块开始,并在以后模块中应用self,super或标识符。
绝对路径和相对路径后跟一个或多个标识符,并用双冒号分隔(::)

例如:

mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // 绝对路径
    crate::front_of_house::hosting::add_to_waitlist();

    // 相对路径
    front_of_house::hosting::add_to_waitlist();
}

运行cargo build会报错:

D:\learn\cargo_learn>cargo build
   Compiling cargo_learn v0.1.0 (D:\learn\cargo_learn)
error[E0603]: module `hosting` is private
 --> src\lib.rs:9:28
  |
9 |     crate::front_of_house::hosting::add_to_waitlist();
  |                            ^^^^^^^ private module
  |
note: the module `hosting` is defined here
 --> src\lib.rs:2:5
  |
2 |     mod hosting {
  |     ^^^^^^^^^^^

error[E0603]: module `hosting` is private
  --> src\lib.rs:12:21
   |
12 |     front_of_house::hosting::add_to_waitlist();
   |                     ^^^^^^^ private module
   |
note: the module `hosting` is defined here
  --> src\lib.rs:2:5
   |
2  |     mod hosting {
   |     ^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0603`.
error: could not compile `cargo_learn`.

To learn more, run the command again with --verbose.

谬误音讯表明模块托管是公有的。换句话说,咱们领有托管模块和add_to_waitlist函数的正确门路,但Rust无法访问它们,因为它无法访问公有局部。

模块不仅仅对组织代码有用。它们还定义了Rust的隐衷边界:封装实现细节的行不容许内部代码晓得,调用或依赖。因而,如果要将我的项目设为函数或构造公有,则将其放在模块中。

Rust中隐衷的工作形式是默认状况下所有我的项目(函数,办法,构造,枚举,模块和常量)都是公有的。父模块中的我的项目不能应用子模块中的公有我的项目,然而子模块中的我的项目能够应用其先人模块中的我的项目。起因是子模块包装并暗藏了其实现详细信息,然而子模块能够看到定义它们的上下文。要持续应用餐厅的隐喻,能够将隐衷规定视为餐厅的后盾办公室:餐厅客户的隐衷是私人的,但办公室经理能够查看并在其经营的餐厅中做任何事件。

Rust抉择以这种形式使模块零碎起作用,以便默认暗藏外部实现细节。这样,您就晓得能够更改外部代码的哪些局部而不会毁坏内部代码。然而,您能够应用pub关键字将我的项目公开,从而将子模块代码的外部局部公开给内部先人模块。

因而咱们须要将应用到的paths裸露进去,通过应用关键字pub

mod front_of_house {
   pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

pub fn eat_at_restaurant() {
    // 绝对路径
    crate::front_of_house::hosting::add_to_waitlist();

    // 相对路径
    front_of_house::hosting::add_to_waitlist();
}

运行:cargo build

D:\learn\cargo_learn>cargo build
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s

D:\learn\cargo_learn>

通过super实现相对路径

在rust中mod中的函数通过应用super::拜访与上一级同级别的paths:

fn serve_order() {}

mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        super::serve_order();
    }

    fn cook_order() {}
}

fn main() {}

公开构造和枚举

咱们还能够应用pub将构造和枚举指定为公共,但还有一些其余细节。 如果咱们在构造定义之前应用pub,则将构造公开,但构造的字段仍将是公有的。 咱们能够依据状况将每个字段公开或不公开。 在下例中,咱们定义了一个公共的back_of_house :: Breakfast构造,其中蕴含一个公共的toast字段,但一个公有的season_fruit字段。 这样能够在一家餐厅中模仿状况,客户能够在这家餐厅抉择餐点附带的面包类型,然而厨师会依据节令和库存来决定餐点中搭配哪种水果。 可用的水果变动很快,因而客户无奈抉择水果,甚至看不到他们会失去哪种水果。

#![allow(unused_variables)]
fn main() {
    mod back_of_house {
        pub struct Breakfast {
            pub toast: String,
            seasonal_fruit: String,
        }

        impl Breakfast {
            pub fn summer(toast: &str) -> Breakfast {
                Breakfast {
                    toast: String::from(toast),
                    seasonal_fruit: String::from("peaches"),
                }
            }
        }
    }

    pub fn eat_at_restaurant() {
        // 通过summer订购黑麦面包早餐
        let mut meal = back_of_house::Breakfast::summer("Rye");
        // 扭转主见,想吃什么面包
        meal.toast = String::from("Wheat");
        println!("我喜爱 {} 吐司,谢谢", meal.toast);

        // 如果咱们勾销正文,则下一行将不会编译; 咱们不容许查看或批改seasonal_fruit
        // meal.seasonal_fruit = String::from("blueberries");
    }
}

与之不同的是,如果咱们将一个枚举公开,则其所有变体都将公开。咱们只须要pub在enum关键字之前,如下所示:

#![allow(unused_variables)]
fn main() {
    mod back_of_house {
        pub enum Appetizer {
            Soup,
            Salad,
        }
    }

    pub fn eat_at_restaurant() {
        let order1 = back_of_house::Appetizer::Soup;
        let order2 = back_of_house::Appetizer::Salad;
    }
}

因为咱们公开了Appetizer枚举,所以咱们能够在eat_at_restaurant中应用Soup和Salad变体。 枚举不是很有用,除非它们的变体是公开的。 在每种状况下都必须用pub正文所有枚举变量会很烦人,因而枚举变量的默认设置是公开的。 构造通常在不公开其字段的状况下很有用,因而,构造字段遵循通常所有内容都默认为公有的个别规定,除非应用pub正文。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理