Chuyển tới nội dung chính

🛣️ Use và Paths: Import Items

🎯 Mục Tiêu Bài Học

Sau khi hoàn thành bài học này, bạn sẽ:

  • ✅ Sử dụng use keyword để import
  • ✅ Hiểu absolute và relative paths
  • ✅ Re-export với pub use
  • ✅ Import nhiều items
  • ✅ Áp dụng use idioms và best practices

🤔 Use Là Gì?

Ẩn Dụ Cuộc Sống: Tạo Shortcut

use giống như tạo shortcut trên desktop:

🖥️ Không Dùng Shortcut:

  • Phải mở C:\Program Files\App\bin\program.exe mỗi lần
  • Dài dòng, khó nhớ

Dùng Shortcut:

  • Click icon trên desktop
  • Nhanh, tiện lợi

📝 use Trong Rust:

  • Tạo shortcut cho paths dài
  • Gọn code, dễ đọc

Ví Dụ Cơ Bản

// Không dùng use
mod math {
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
}

fn main() {
let result = math::add(5, 3); // Gọi đầy đủ
}

// Dùng use
mod math {
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
}

use math::add;

fn main() {
let result = add(5, 3); // Gọn hơn!
}

📍 Absolute vs Relative Paths

Absolute Path

Bắt đầu từ crate root:

use crate::module::function;
use std::collections::HashMap;

Relative Path

Bắt đầu từ module hiện tại:

use self::submodule::function;
use super::parent_function;

Ví Dụ

mod parent {
pub fn parent_fn() {}

pub mod child {
pub fn child_fn() {}

pub fn use_parent() {
// Absolute path
crate::parent::parent_fn();

// Relative path với super
super::parent_fn();
}
}
}

use parent::child::child_fn; // Absolute từ crate root

fn main() {
child_fn();
}

📦 Import Patterns

Single Item

use std::collections::HashMap;

fn main() {
let mut map = HashMap::new();
map.insert("key", "value");
}

Multiple Items

use std::collections::{HashMap, HashSet, BTreeMap};

fn main() {
let map = HashMap::new();
let set = HashSet::new();
let btree = BTreeMap::new();
}

Nested Paths

use std::{
collections::HashMap,
io::{self, Write},
fmt::Display,
};

Glob Import

use std::collections::*;

fn main() {
let map = HashMap::new();
let set = HashSet::new();
// Tất cả items từ collections
}

Cảnh báo: Tránh glob import! Dễ confusing.

Aliasing

use std::collections::HashMap as Map;

fn main() {
let mut map = Map::new();
map.insert("key", "value");
}

🔄 Re-exporting với pub use

Flatten Module Structure

mod inner {
pub mod deep {
pub fn function() {
println!("Deep function");
}
}
}

// Re-export
pub use inner::deep::function;

fn main() {
// Thay vì
// inner::deep::function();

// Có thể gọi
function();
}

Create Public API

mod internal {
pub fn helper1() {}
pub fn helper2() {}
fn private_helper() {} // Không export
}

// Public API
pub use internal::{helper1, helper2};
// private_helper không available từ bên ngoài

🎯 Use Idioms

Idiomatic Imports

// ✅ Good - import module
use std::collections::HashMap;
let map = HashMap::new();

// ✅ Good - import trait để dùng methods
use std::io::Write;
file.write_all(b"text")?;

// ❌ Avoid - import function directly
use std::collections::HashMap::new;
let map = new(); // Confusing!

Traits

use std::fmt::Display;

fn print_it<T: Display>(value: T) {
println!("{}", value);
}

Standard Library

// Prefer
use std::collections::HashMap;

// Over
use std::collections::*; // Too broad

🎯 Ví Dụ Thực Tế

Ví Dụ 1: Project Structure

// src/lib.rs
mod database;
mod api;

pub use database::{connect, query};
pub use api::Router;

// External users can use:
// use my_lib::{connect, query, Router};

Ví Dụ 2: Prelude Pattern

// src/prelude.rs
pub use crate::errors::Error;
pub use crate::config::Config;
pub use crate::utils::helpers::*;

// src/lib.rs
pub mod prelude;

// Users can do:
// use my_lib::prelude::*;
// Gets Error, Config, helpers in one go

Ví Dụ 3: Organized Imports

// Standard library
use std::collections::HashMap;
use std::io::{self, Write};

// External crates
use serde::{Deserialize, Serialize};
use tokio::runtime::Runtime;

// Internal modules
use crate::config::Config;
use crate::database::connect;

fn main() {
// ...
}

💻 Bài Tập Thực Hành

Bài 1: Use Statement

mod math {
pub fn add(a: i32, b: i32) -> i32 {
a + b
}

pub fn multiply(a: i32, b: i32) -> i32 {
a * b
}
}

// TODO: Import add và multiply
// use ...

fn main() {
println!("{}", add(5, 3));
println!("{}", multiply(5, 3));
}
💡 Gợi ý
use math::{add, multiply};

Bài 2: Re-export

mod internal {
pub mod helpers {
pub fn helper_fn() {
println!("Helper");
}
}
}

// TODO: Re-export helper_fn để gọi trực tiếp
// pub use ...

fn main() {
helper_fn(); // Should work
}
💡 Gợi ý
pub use internal::helpers::helper_fn;

🎯 Tóm Tắt

PatternCú PhápKhi Nào Dùng
Basicuse mod::itemImport single item
Multipleuse mod::{A, B}Import nhiều items
Nesteduse std::{io, fs}Organize imports
Aliasuse mod::item as XAvoid naming conflicts
Re-exportpub useCreate public API
Globuse mod::*Tránh! (trừ prelude)

Quy tắc vàng:

  • ✅ Import modules, not functions (trừ traits)
  • ✅ Group imports: std → external → internal
  • ✅ Use pub use để flatten public API
  • ✅ Tránh glob imports
  • ✅ Alias để tránh naming conflicts

🔗 Liên Kết Hữu Ích


Bài tiếp theo: HashMap →

Trong bài tiếp theo, chúng ta sẽ tìm hiểu về HashMap - collection key-value!

Loading comments...