use 关键字
use 关键字用于将模块路径引入当前作用域,让你可以更简洁地使用模块中的项目。这类似于其他语言中的 import 或 include。
基本用法
引入函数
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
// 使用 use 引入函数
use crate::front_of_house::hosting::add_to_waitlist;
pub fn eat_at_restaurant() {
add_to_waitlist(); // 直接调用,无需完整路径
}
引入模块
use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist(); // 通过模块名调用
}
相对路径和绝对路径
绝对路径
// 从 crate 根开始
use crate::front_of_house::hosting;
// 从外部 crate 开始
use std::collections::HashMap;
use rand::Rng;
相对路径
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
// 相对路径引入
use front_of_house::hosting;
// 使用 self
use self::front_of_house::hosting as self_hosting;
// 使用 super
mod parent {
fn parent_function() {}
mod child {
use super::parent_function; // 引入父模块的函数
}
}
as 关键字 - 重命名
use std::fmt::Result;
use std::io::Result as IoResult; // 重命名避免冲突
fn function1() -> Result<(), String> { // fmt::Result
Ok(())
}
fn function2() -> IoResult<()> { // io::Result
Ok(())
}
重命名示例
use std::collections::HashMap as Map;
use std::collections::BTreeMap as OrderedMap;
fn main() {
let mut scores: Map<String, i32> = Map::new();
let mut ordered_scores: OrderedMap<String, i32> = OrderedMap::new();
scores.insert("Blue".to_string(), 10);
ordered_scores.insert("Red".to_string(), 20);
}
嵌套路径
基本嵌套
// 传统方式
use std::cmp::Ordering;
use std::io;
// 嵌套路径
use std::{cmp::Ordering, io};
复杂嵌套
// 传统方式
use std::io;
use std::io::Write;
// 嵌套路径使用 self
use std::io::{self, Write};
多层嵌套
use std::collections::{
HashMap,
BTreeMap,
HashSet,
};
// 或者在一行
use std::collections::{HashMap, BTreeMap, HashSet};
glob 操作符
使用 * 引入模块中的所有公开项目:
use std::collections::*;
fn main() {
let mut map = HashMap::new(); // 直接使用
let mut set = HashSet::new(); // 直接使用
}
谨慎使用 glob
// 好的使用场景:测试模块
#[cfg(test)]
mod tests {
use super::*; // 引入父模块的所有项目
#[test]
fn test_function() {
// 可以直接使用父模块的函数
}
}
// 避免在生产代码中过度使用
// use std::*; // 不推荐,会污染命名空间
pub use - 重新导出
pub use 允许你重新导出项目,让其他模块可以通过你的模块访问:
// src/lib.rs
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
// 重新导出,让外部可以直接访问
pub use crate::front_of_house::hosting;
// 现在外部可以这样使用:
// use restaurant::hosting;
创建便利的 API
// src/lib.rs
mod models {
pub mod user {
pub struct User {}
}
pub mod post {
pub struct Post {}
}
}
mod handlers {
pub mod user_handler {
pub fn create_user() {}
}
}
// 重新导出,创建扁平的 API
pub use models::user::User;
pub use models::post::Post;
pub use handlers::user_handler::create_user;
// 外部使用者可以这样导入:
// use my_crate::{User, Post, create_user};
条件导入
基于特性的导入
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[cfg(feature = "serde")]
#[derive(Serialize, Deserialize)]
struct MyStruct {
field: String,
}
基于平台的导入
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
#[cfg(windows)]
use std::os::windows::fs::OpenOptionsExt;
外部 crate 导入
标准库
use std::collections::HashMap;
use std::fs::File;
use std::io::{self, Read, Write};
use std::thread;
use std::time::Duration;
第三方 crate
// Cargo.toml 中添加依赖后
use serde::{Serialize, Deserialize};
use tokio::time::sleep;
use reqwest::Client;
use clap::{App, Arg};
最佳实践
1. 导入顺序
// 1. 标准库
use std::collections::HashMap;
use std::fs::File;
// 2. 第三方 crate
use serde::{Serialize, Deserialize};
use tokio::time::sleep;
// 3. 当前 crate
use crate::models::User;
use crate::handlers::create_user;
// 4. 相对导入
use super::parent_function;
2. 分组和空行
use std::collections::HashMap;
use std::fs::File;
use serde::{Serialize, Deserialize};
use tokio::time::sleep;
use crate::models::{User, Post};
use crate::handlers::user_handler;
3. 避免过度嵌套
// 好的
use std::collections::HashMap;
use std::io::{self, Write};
// 避免过度复杂的嵌套
use std::{
collections::{HashMap, BTreeMap},
io::{self, Write, Read},
fs::{File, OpenOptions},
};
4. 合理使用重命名
// 解决命名冲突
use std::fmt::Result;
use std::io::Result as IoResult;
// 简化长名称
use very_long_crate_name::very_long_module_name as short_name;
// 提高可读性
use crate::database::connection::DatabaseConnection as DbConn;
常见模式
预导入模块 (Prelude)
// src/prelude.rs
pub use crate::models::{User, Post, Comment};
pub use crate::handlers::{create_user, create_post};
pub use crate::utils::{validate_email, hash_password};
// src/lib.rs
pub mod prelude;
// 使用者可以这样导入:
// use my_crate::prelude::*;
模块重新组织
// src/lib.rs
mod internal {
pub mod user;
pub mod post;
}
// 重新导出到更好的结构
pub mod models {
pub use crate::internal::user::User;
pub use crate::internal::post::Post;
}
错误处理
常见错误
// 错误:项目不存在
use std::collections::NonExistentType; // 编译错误
// 错误:项目是私有的
mod private_mod {
fn private_function() {}
}
use private_mod::private_function; // 编译错误
// 错误:循环导入
// 模块 A 导入模块 B,模块 B 又导入模块 A
解决方案
// 使用 pub 使项目公开
mod my_mod {
pub fn public_function() {}
}
use my_mod::public_function; // 正确
// 重构避免循环依赖
// 将共同依赖提取到单独的模块
use 关键字是 Rust 模块系统的重要组成部分,合理使用它可以让你的代码更加清晰和易于维护。下一节我们将学习 crate 和包的概念。