If you find this helpful, please like, bookmark, and follow. To keep learning along, follow this series.
7.3.1 super
We can access items in a parent module’s path by using super at the start of a path, just like using .. syntax to start a file-system path. For example:
fn deliver_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::deliver_order();
}
fn cook_order() {}
}
Of course, you can use an absolute path to achieve the same result:
fn deliver_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
crate::deliver_order();
}
fn cook_order() {}
}
7.3.2 pub struct
If you put the pub keyword before struct, the struct becomes public, as shown below:
mod back_of_house {
pub struct Breakfast {
toast: String,
seasonal_fruit: String,
}
}
Note that although this struct is public, the fields inside a struct are private by default, unless you add the pub keyword.
In Rust, in most cases if something does not have pub, then it is private. (Special cases will be discussed later.)
Making a field public is also simple. Here is the code after changing toast in Breakfast to public:
mod back_of_house {
pub struct Breakfast {
pub toast: String,
seasonal_fruit: String,
}
}
Let’s look at a more complex example:
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(){
let mut meal = back_of_house::Breakfast::summer("Rye");
meal.toast = String::from("Wheat");
}
- On top of the struct, we define an associated function
summer, whose parameter is the string slicetoastand whose return value isBreakfast. The value ofBreakfast.toastwill be the value of that argument, and the value ofBreakfast.seasonal_fruitwill be set topeaches. In essence,summeris a constructor that creates an instance ofBreakfast. - In the
eat_at_restaurantfunction, we first use a relative path to callsummerand construct an instance, then assign it to the mutable variablemeal. Thetoastfield inmealis set toRye, andseasonal_fruitispeachesas written in the constructor. On the next line, because theBreakfaststruct is public,meal.toastcan be modified directly, and here it is changed toWheat.
Would writing meal.seasonal_fruit = String::from("buleberries"); inside the eat_at_restaurant function cause an error? The answer is yes, because fields inside a struct are private by default. seasonal_fruit was not declared public, so external code cannot modify it, and this line attempts to modify it, which causes an error.
7.3.3 pub enum
Just like struct, an enum also becomes public if you add the pub keyword. For example:
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;
}
But unlike struct, where the fields are private by default, the variants of a public enum are public by default, so you do not need to put pub before each variant. This differs from Rust’s default-private rule because only public variants on a public enum are useful, while having some private fields in a struct does not affect its use.
But note that the prerequisite for variants of an enum to be public is that the enum itself is declared public.