+1

[Programming 101] Return Void là gì? Khi "không trả về gì" lại mang lại giá trị lớn nhất

1. Bản chất của "Void"

Trong lập trình, void là một kiểu dữ liệu đặc biệt (hoặc một từ khóa) dùng để thông báo cho trình biên dịch hoặc người đọc code rằng: "Hàm này thực hiện một nhiệm vụ, nhưng nó sẽ không trả lại bất kỳ kết quả nào cho người gọi nó".

Nếu một hàm trả về int, nó đưa cho bạn một con số. Nếu nó trả về void, nó chỉ đơn giản là thực hiện xong việc rồi... im lặng.

2. Tại sao chúng ta cần những hàm "không lời"? (Side Effects)

Tại sao không bắt mọi hàm đều phải trả về một cái gì đó cho chắc ăn? Câu trả lời nằm ở khái niệm Side Effects (Tác dụng phụ).

Những hàm void thường không dùng để tính toán giá trị, mà dùng để thay đổi trạng thái của hệ thống. Ví dụ:

  • Ghi dữ liệu: Lưu một đơn hàng vào Database.
  • Gửi thông báo: Bắn một email Welcome cho user.
  • Log dữ liệu: Ghi lại vết lỗi vào file log.
  • Thay đổi thuộc tính: Cập nhật trạng thái của một Object trong bộ nhớ.

Nếu anh em cố tình bắt những hàm này trả về một giá trị (như true/false hay 1/0), đôi khi anh em đang làm rối người đọc code vì họ sẽ phải tự hỏi: "Ủa, cái giá trị trả về này dùng để làm gì tiếp theo đây?".

3. "Void" trong các ngôn ngữ anh em hay dùng

Trong PHP (Laravel context)

Từ bản PHP 7.1 trở đi, chúng ta đã có thể khai báo kiểu trả về là void. Đây là cách cực tốt để anh em "ép" code của mình phải chuẩn chỉ.

public function updateStatus(int $orderId, string $status): void
{
    // Logic cập nhật database
    DB::table('orders')->where('id', $orderId)->update(['status' => $status]);
    
    // Nếu bạn cố tình 'return $something;' ở đây, PHP sẽ báo lỗi ngay!
}

Trong JavaScript/Node.js

JavaScript không có từ khóa void bắt buộc trong khai báo hàm như PHP hay Java, nhưng một hàm không có lệnh return sẽ mặc định trả về undefined. Tuy nhiên, trong TypeScript, việc khai báo void là một thói quen bắt buộc của các "pro" để quản lý luồng dữ liệu chặt chẽ.

Trong Go (Golang)

Go thậm chí còn đơn giản hơn. Nếu bạn không khai báo kiểu trả về trong chữ ký hàm (function signature), thì hàm đó mặc định là "void".

4. Nghệ thuật Clean Code: Quy tắc CQS (Command-Query Separation)

Việc sử dụng void đúng cách giúp anh em tuân thủ nguyên lý CQS - một trong những nguyên lý vàng của lập trình hướng đối tượng:

  1. Queries (Truy vấn): Trả về kết quả và không làm thay đổi trạng thái hệ thống (Hàm có return).

  2. Commands (Lệnh): Làm thay đổi trạng thái hệ thống nhưng không trả về kết quả (Hàm void).

    Bí kíp: Khi nhìn thấy một hàm void, người đọc code sẽ hiểu ngay: "À, đây là một câu lệnh, nó sẽ đi làm cái gì đó (như lưu DB, gửi mail) chứ không phải đi tính toán rồi trả về kết quả". Việc phân tách này giúp anh em tránh được những lỗi "Side effect" quái đản khi chỉ muốn lấy dữ liệu mà vô tình làm thay đổi luôn dữ liệu đó.

5. Khi nào thì dùng return; trong hàm void?

Dù hàm không trả về giá trị, anh em vẫn có thể dùng từ khóa return; (không kèm theo gì phía sau). Mục đích duy nhất của nó lúc này là để thoát khỏi hàm sớm (Early Return).

public function processOrder(Order $order): void
{
    if ($order->isProcessed()) {
        return; // Thoát ngay, không làm gì tiếp theo vì đơn đã xử lý rồi
    }

    // Tiếp tục các logic xử lý nặng nề phía dưới...
}

Lời kết

Return void không phải là "vô dụng", nó là một lời cam kết thép của anh em với những lập trình viên khác rằng: "Tôi đi thực hiện nhiệm vụ, đừng đợi kết quả từ tôi, hãy cứ tin là tôi sẽ làm xong". Sử dụng void đúng chỗ chính là cách anh em làm cho mã nguồn của mình trở nên minh bạch và dễ dự đoán hơn.

Anh em có thói quen khai báo kiểu trả về void cho hàm không, hay cứ để mặc định cho tiện? Anh em thấy việc bắt buộc khai báo void có làm tốn thời gian hơn không? Cùng chia sẻ quan điểm ở dưới comment nhé!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.