模块暴露
pub 规则
结构,枚举,特征或模块的pub
怎么样?
- Struct:将结构公开,但项目不公开。要公开一个项目,您也必须为每个项目都写一个
pub
。 Enum 或者Trait :一切都公开了。这是有道理的,因为特质是关于赋予某物相同的行为。枚举是关于项目之间的选择的,您需要查看它们才能选择它们。- Module:第一个模块将是
pub
,因为如果不是pub ,那么任何人都无法触摸其中的任何内容。但是模块内部的模块需要将pub
公开。
因此,让我们在"Billy".to_string()
的结构。但是用户可以选择打印次数,这样可以公开显示。看起来像这样:
mod print_things {
use std::fmt::{Display, Debug};
#[derive(Debug)]
pub struct Billy { // Billy is public
name: String, // but name is private.
pub times_to_print: u32,
}
impl Billy {
pub fn new(times_to_print: u32) -> Self { // That means the user needs to use new to create a Billy. The user can only input times_to_print
Self {
name: "Billy".to_string(), // We choose the name - the user can't
times_to_print,
}
}
pub fn print_billy(&self) { // This function prints a Billy
for _ in 0..self.times_to_print {
println!("{:?}", self.name);
}
}
}
pub fn prints_one_thing<T: Display>(input: T) {
println!("{}", input)
}
}
fn main() {
use crate::print_things::*; // Now we use *. This imports everything from print_things
let my_billy = Billy::new(3);
my_billy.print_billy();
}
"Billy"
"Billy"
"Billy"
模块嵌套
在
mod country { // The main mod doesn't need pub
fn print_country(country: &str) { // Note: this function isn't public
println!("We are in the country of {}", country);
}
pub mod province { // Make this mod public
fn print_province(province: &str) { // Note: this function isn't public
println!("in the province of {}", province);
}
pub mod city { // Make this mod public
pub fn print_city(country: &str, province: &str, city: &str) { // This function is public though
crate::country::print_country(country);
crate::country::province::print_province(province);
println!("in the city of {}", city);
}
}
}
}
fn main() {
crate::country::province::city::print_city("Canada", "New Brunswick", "Moncton");
}
有趣的是,crate::country::province::print_province(province);
很长,当我们在模块内部时,我们可以使用
mod country {
fn print_country(country: &str) {
println!("We are in the country of {}", country);
}
pub mod province {
fn print_province(province: &str) {
println!("in the province of {}", province);
}
pub mod city {
use super::super::*; // use everything in "above above": that means mod country
use super::*; // use everything in "above": that means mod province
pub fn print_city(country: &str, province: &str, city: &str) {
print_country(country);
print_province(province);
println!("in the city of {}", city);
}
}
}
}
fn main() {
use crate::country::province::city::print_city; // bring in the function
print_city("Canada", "New Brunswick", "Moncton");
print_city("Korea", "Gyeonggi-do", "Gwangju"); // Now it's less work to use it again
}
Re-exporting
我们可以结合使用 pub use
来实现 Re-exporting
。Re-exporting
的字面意思就是重新导出。它的意思是这样的,把深层的a::b::c::d
的例子。我们在 main.rs
中,要调用 d
,得使用 use a::b::c::d;
来调用。而如果我们修改 a/mod.rs
文件为:a/mod.rs
文件内容:
pub mod b;
pub use b::c::d;
那么,我们在 main.rs
中,就可以使用 use a::d;
来调用了。从这个例子来看没觉得方便多少。但是如果开发的一个库中有大量的内容,而且是在不同层次的模块中。那么,通过统一导出到一个地方,就能大大方便接口使用者。