跳到主要内容

use 关键字

use 关键字用于将模块路径引入当前作用域,让你可以更简洁地使用模块中的项目。这类似于其他语言中的 importinclude

基本用法

引入函数

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 和包的概念。