---
title: "Lập trình Rust Cơ Bản: Giới Thiệu Generics – Viết Code Linh Hoạt và Tái Sử Dụng"
description: "Lập trình Rust Cơ Bản: Giới Thiệu Generics - Viết Code Linh Hoạt và Tái Sử Dụng"
date: "2026-09-07"
author:
  name: "Nguyen Pham"
  role: "Xin chào. Mình thích lập trình và công nghệ. Đây là blog mình chia sẻ lại các kiến thức về lập trình, công nghệ."
  avatar: "http://0.gravatar.com/avatar/6fb61398e24046b34e13870dd6c357b9?s=128&d=mm&r=g"
category: "Blog"
tags: ["Blog"]
coverImage: "/blog/covers/lap-trinh-rust-co-ban-gioi-thieu-generics-viet-code-linh-hoat-va-tai-su-dung.png"
featured: false
readingTime: "5 min read"
---

Trong hành trình **Lập trình Rust Cơ Bản**, *generics* là một trong những công cụ mạnh mẽ nhất giúp bạn viết **code linh hoạt** và **tái sử dụng** một cách tối ưu. Bài viết này sẽ giải thích khái niệm, cách sử dụng và cung cấp các ví dụ thực tế để bạn nhanh chóng áp dụng vào dự án của mình.

## 1. Generics là gì?

Generics (kiểu tổng quát) trong Rust cho phép bạn định nghĩa các hàm, struct, enum mà không cần chỉ định kiểu dữ liệu cụ thể ngay từ đầu. Thay vào đó, kiểu sẽ được “đổ” (instantiate) khi bạn gọi chúng, giúp giảm thiểu việc lặp lại mã và tăng tính **tái sử dụng**.

## 2. Tại sao cần Generics trong Rust?

- **Code linh hoạt:** Một hàm hoặc struct có thể làm việc với nhiều kiểu dữ liệu khác nhau.
- **An toàn về kiểu:** Rust vẫn giữ được kiểm tra kiểu tại thời điểm biên dịch, tránh lỗi runtime.
- **Tối ưu hiệu năng:** Không có overhead của polymorphism động; mọi thứ được tối ưu ở compile-time.
- **Dễ bảo trì:** Giảm số lượng hàm lặp lại, làm cho dự án sạch sẽ hơn.

## 3. Cú pháp cơ bản của Generics

### 3.1. Hàm generic

```
fn print_value(value: T) {
    println!("Giá trị: {}", value);
}
```

Ở đây `T` là một placeholder cho bất kỳ kiểu nào thực hiện trait `Display`. Hàm `print_value` có thể nhận `i32`, `f64`, `String`, …

### 3.2. Struct generic

```
struct Pair<T, U> {
    first: T,
    second: U,
}

impl<T, U> Pair<T, U> {
    fn new(first: T, second: U) -> Self {
        Self { first, second }
    }
}
```

## 4. Các trait bound phổ biến

Để giới hạn các kiểu có thể được sử dụng, bạn dùng **trait bounds**. Dưới đây là một số ví dụ thường gặp:

- `T: Clone` – Kiểu phải hỗ trợ phương thức `clone()`.
- `T: PartialOrd` – Kiểu có thể so sánh thứ tự.
- `T: std::ops::Add<Output = T>` – Kiểu hỗ trợ phép cộng.

## 5. Ví dụ thực tế: Stack generic

Hãy xây dựng một `Stack` có thể chứa bất kỳ kiểu dữ liệu nào.

```
#[derive(Debug)]
struct Stack<T> {
    items: Vec<T>,
}

impl<T> Stack<T> {
    fn new() -> Self {
        Self { items: Vec::new() }
    }

    fn push(&mut self, item: T) {
        self.items.push(item);
    }

    fn pop(&mut self) -> Option<T> {
        self.items.pop()
    }

    fn peek(&self) -> Option<&T> {
        self.items.last()
    }
}

fn main() {
    let mut int_stack = Stack::new();
    int_stack.push(10);
    int_stack.push(20);
    println!("Stack int: {:?}", int_stack);

    let mut str_stack = Stack::new();
    str_stack.push(String::from("rust"));
    str_stack.push(String::from("generics"));
    println!("Stack string: {:?}", str_stack);
}
```

Đoạn code trên minh hoạ cách **viết code linh hoạt** và **tái sử dụng** một cấu trúc dữ liệu mà không cần viết lại cho mỗi kiểu dữ liệu.

## 6. Khi nào nên tránh Generics?

Mặc dù generics mạnh mẽ, nhưng không phải lúc nào cũng là lựa chọn tốt nhất. Hãy cân nhắc:

- Quá nhiều bound phức tạp có thể làm mã khó đọc.
- Nếu chỉ cần một kiểu duy nhất, việc dùng generic có thể gây dư thừa.
- Trong các trường hợp cần *dynamic dispatch*, trait objects (`Box<dyn Trait>`) có thể phù hợp hơn.

## 7. Tài nguyên học thêm

- [The Rust Book – Traits](https://doc.rust-lang.org/book/ch10-02-traits.html)
- [Rust Standard Library – Add Trait](https://doc.rust-lang.org/std/ops/trait.Add.html)
- [Rustlings – Bài tập thực hành](https://github.com/rust-lang/rustlings)

## Kết luận

Generics là một phần cốt lõi của **Lập trình Rust Cơ Bản** giúp bạn viết **code linh hoạt**, **tái sử dụng** và vẫn giữ được hiệu năng tuyệt vời của Rust. Bằng cách nắm vững các khái niệm như trait bound, impl generic và các ví dụ thực tế, bạn sẽ tự tin áp dụng generics vào mọi dự án, từ những chương trình nhỏ đến các hệ thống phức tạp.

Hãy thử tạo một vài struct hoặc hàm generic ngay hôm nay và cảm nhận sự khác biệt! Nếu bạn có câu hỏi hoặc muốn chia sẻ kinh nghiệm, đừng ngần ngại để lại bình luận bên dưới.
