Added most of chapter 10

This commit is contained in:
2020-06-11 21:32:42 -04:00
parent 3710fe0b0e
commit f671338dde
7 changed files with 259 additions and 0 deletions

5
src/Modules.rs Normal file
View File

@@ -0,0 +1,5 @@
pub mod Visibility;
pub mod StructVisibility;
pub mod TheUseDeclaration;
pub mod SuperAndSelf;
pub mod FileHierarchy;

View File

View File

@@ -0,0 +1,42 @@
mod my{
// A public struct with a public field of generic type `T`
pub struct OpenBox<T>{
pub contents: T,
}
// A public struct with a private field of generic type `T`
#[allow(dead_code)]
pub struct ClosedBox<T>{
contents: T,
}
impl<T> ClosedBox<T>{
//A public constructor method
pub fn new(contents: T) -> ClosedBox<T>{
ClosedBox{
contents: contents,
}
}
}
}
pub fn main(){
//Public structs with public fields can be constructed as usual
let open_box = my::OpenBox { contents: "public information" };
//and their fields can be normally accessed.
println!("The open box contains: {}", open_box.contents);
//Public structs with private fields cannot be constructed using field names.
//Error! `ClosedBox` has private fields
//let closed_box = my::ClosedBox { contents: "classified information" };
//TODO ^ Try uncommenting this line
//However, structs with private fields can be created using public constructors
let _closed_box = my::ClosedBox::new("classified information");
//and the private fields of a public struct cannot be accessed.
//Error! The `contents` field is private
//println!("The closed box contains: {}", _closed_box.contents);
//TODO ^ Try uncommenting this line
}

View File

@@ -0,0 +1,48 @@
fn function(){
println!("called `function()`");
}
mod cool{
pub fn function(){
println!("called `cool::function()`");
}
}
mod my{
fn function(){
println!("called `my::function()`");
}
mod cool{
pub fn function(){
println!("called `my::cool::function()`");
}
}
pub fn indirect_call(){
//Let's access all the functions named `function` from this scope!
print!("called `my::indirect_call()`, that\n> ");
//The `self` keyword refers to the current module scope - in this case `my`.
//Calling `self::function()` and calling `function()` directly both give the same result, because they refer to the same function.
self::function();
function();
//We can also use `self` to access another module inside `my`:
self::cool::function();
//The `super` keyword refers to the parent scope (outside the `my` module).
super::function();
//This will bind to the `cool::function` in the *crate* scope.
//In this case the crate scope is the outermost scope.
{
use crate::Modules::SuperAndSelf::cool::function as root_function;
root_function();
}
}
}
pub fn main(){
my::indirect_call();
}

View File

@@ -0,0 +1,32 @@
// Bind the `deeply::nested::function` path to `other_function`.
use deeply::nested::function as other_function;
fn function(){
println!("called `function()`");
}
mod deeply{
pub mod nested{
pub fn function(){
println!("called `deeply::nested::function()`");
}
}
}
pub fn main(){
//Easier access to `deeply::nested::function`
other_function();
println!("Entering block");
{
//This is equivalent to `use deeply::nested::function as function`.
//This `function()` will shadow the outer one.
use crate::Modules::TheUseDeclaration::deeply::nested::function;
function();
//`use` bindings have a local scope. In this case, the shadowing of `function()` is only in this block.
println!("Leaving block");
}
function();
}

113
src/Modules/Visibility.rs Normal file
View File

@@ -0,0 +1,113 @@
//A module named `my_mod`
mod my_mod{
//Items in modules default to private visibility.
fn private_function(){
println!("called `my_mod::private_function()`");
}
//Use the `pub` modifier to override default visibility.
pub fn function(){
println!("called `my_mod::function()`");
}
//Items can access other items in the same module, even when private.
pub fn indirect_access(){
print!("called `my_mod::indirect_access()`, that\n> ");
private_function();
}
//Modules can also be nested
pub mod nested{
pub fn function(){
println!("called `my_mod::nested::function()`");
}
#[allow(dead_code)]
fn private_function(){
println!("called `my_mod::nested::private_function()`");
}
//Functions declared using `pub(in path)` syntax are only visible within the given path. `path` must be a parent or ancestor module
pub(in crate::Modules::Visibility::my_mod) fn public_function_in_my_mod(){
print!("called `my_mod::nested::public_function_in_my_mod()`, that\n> ");
public_function_in_nested();
}
//Functions declared using `pub(self)` syntax are only visible within the current module, which is the same as leaving them private
pub(self) fn public_function_in_nested(){
println!("called `my_mod::nested::public_function_in_nested()`");
}
//Functions declared using `pub(super)` syntax are only visible within the parent module
pub(super) fn public_function_in_super_mod(){
println!("called `my_mod::nested::public_function_in_super_mod()`");
}
}
pub fn call_public_function_in_my_mod(){
print!("called `my_mod::call_public_function_in_my_mod()`, that\n> ");
nested::public_function_in_my_mod();
print!("> ");
nested::public_function_in_super_mod();
}
//pub(crate) makes functions visible only within the current crate
pub(crate) fn public_function_in_crate(){
println!("called `my_mod::public_function_in_crate()`");
}
//Nested modules follow the same rules for visibility
mod private_nested{
#[allow(dead_code)]
pub fn function(){
println!("called `my_mod::private_nested::function()`");
}
//Private parent items will still restrict the visibility of a child item, even if it is declared as visible within a bigger scope.
#[allow(dead_code)]
pub(crate) fn restricted_function(){
println!("called `my_mod::private_nested::restricted_function()`");
}
}
}
fn function(){
println!("called `function()`");
}
pub fn main(){
//Modules allow disambiguation between items that have the same name.
function();
my_mod::function();
//Public items, including those inside nested modules, can be accessed from outside the parent module.
my_mod::indirect_access();
my_mod::nested::function();
my_mod::call_public_function_in_my_mod();
//pub(crate) items can be called from anywhere in the same crate
my_mod::public_function_in_crate();
//pub(in path) items can only be called from within the module specified
//Error! function `public_function_in_my_mod` is private
//my_mod::nested::public_function_in_my_mod();
//TODO ^ Try uncommenting this line
//Private items of a module cannot be directly accessed, even if nested in a public module:
//Error! `private_function` is private
//my_mod::private_function();
//TODO ^ Try uncommenting this line
//Error! `private_function` is private
//my_mod::nested::private_function();
//TODO ^ Try uncommenting this line
//Error! `private_nested` is a private module
//my_mod::private_nested::function();
//TODO ^ Try uncommenting this line
//Error! `private_nested` is a private module
//my_mod::private_nested::restricted_function();
//TODO ^ Try uncommenting this line
}

View File

@@ -11,6 +11,7 @@ mod Conversion;
mod Expressions;
mod FlowOfControl;
mod Functions;
mod Modules;
fn main(){
@@ -130,6 +131,7 @@ fn main(){
*/
//9 Functions
/*
println!("9. Functions");
Functions::main();
//9.1 Methods
@@ -167,4 +169,21 @@ fn main(){
//9.4 Diverging functions
println!("\n\n9.4 Diverging functions");
Functions::DivergingFunctions::main();
*/
//10 Modules
//10.1 Visibility
println!("\n\n10.1 Visibility");
Modules::Visibility::main();
//10.2 Struct visibility
println!("\n\n10.2 Struct visibility");
Modules::StructVisibility::main();
//10.3 The use declaration
println!("\n\n10.3 The use declaration");
Modules::TheUseDeclaration::main();
//10.4 Super and self
println!("\n\n10.4 Super and self");
Modules::SuperAndSelf::main();
//10.5 File hierarchy
//println!("\n\nFile hierarchy");
}