Controlling Module Visibility with pub in Rust
Rust's module system allows for fine-grained control over code visibility. This challenge focuses on understanding and utilizing the pub keyword to expose specific items (functions, structs, modules) from your modules, enabling you to create reusable and well-defined libraries and applications. Mastering visibility is crucial for building robust and maintainable Rust code.
Problem Description
You are tasked with creating a Rust module named my_module that contains several items: a private struct PrivateData, a public struct PublicData, a private function private_function, and a public function public_function. The goal is to correctly use the pub keyword to ensure that PublicData and public_function are accessible from outside the my_module module, while PrivateData and private_function remain hidden and inaccessible from outside. You will also need to create a main function that demonstrates the usage of the public items.
Key Requirements:
- Create a module named
my_module. - Define a private struct
PrivateData. - Define a public struct
PublicData. - Define a private function
private_functionthat takes ani32and returns ani32. - Define a public function
public_functionthat takes aStringand returns aString. - The
public_functionshould callprivate_functioninternally. - The
mainfunction should create an instance ofPublicData, callpublic_functionwith a string, and print the result to the console. - Attempting to access
PrivateDataorprivate_functionfrom outsidemy_moduleshould result in a compile-time error.
Expected Behavior:
The code should compile and run without errors. The main function should successfully create a PublicData instance, call public_function, and print the returned string to the console. The compiler should prevent access to the private members from outside the module.
Edge Cases to Consider:
- Ensure that the private members are truly inaccessible from outside the module.
- Verify that the public members are accessible as intended.
- Consider how the module structure affects visibility.
Examples
Example 1:
Input: my_module.rs contains:
struct PrivateData { x: i32 }
pub struct PublicData { y: String }
fn private_function(a: i32) -> i32 { a * 2 }
pub fn public_function(s: String) -> String {
let result = private_function(5);
format!("Result: {}", result) + &s
}
main.rs contains:
mod my_module;
use my_module::PublicData;
use my_module::public_function;
fn main() {
let public_data = PublicData { y: "Hello".to_string() };
let result = public_function(" World!".to_string());
println!("{}", result);
}
Output:
Result: 10 World!
Explanation: The public_function is called successfully, demonstrating public visibility. PrivateData and private_function are not used and cannot be accessed from main.rs.
Example 2: (Demonstrating compile-time error)
Input: my_module.rs contains:
struct PrivateData { x: i32 }
pub struct PublicData { y: String }
fn private_function(a: i32) -> i32 { a * 2 }
pub fn public_function(s: String) -> String {
let result = private_function(5);
format!("Result: {}", result) + &s
}
main.rs contains:
mod my_module;
fn main() {
// This line should cause a compile-time error
// let private_data = my_module::PrivateData { x: 10 };
println!("Hello, world!");
}
Output: (Compile-time error)
error[E0309]: field `PrivateData::x` is private
--> src/main.rs:7:14
|
6 | // This line should cause a compile-time error
|
7 | let private_data = my_module::PrivateData { x: 10 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ private field
|
= note: `PrivateData` is private
Explanation: The attempt to create an instance of PrivateData from outside the module results in a compile-time error, confirming that the visibility is correctly restricted.
Constraints
- The solution must be written in Rust.
- The code must compile and run without runtime errors.
- The code must adhere to Rust's ownership and borrowing rules.
- The solution should be concise and readable.
- The
public_functionmust callprivate_functioninternally.
Notes
- Think carefully about where you place the
pubkeyword to control visibility. - Rust's module system is a powerful tool for organizing and controlling code access.
- Compile-time errors are your friend! They help you catch visibility issues early.
- Consider using
modkeyword to define the module. - The
mainfunction should be in a separate file (e.g.,main.rs) and import the module.