Hàm ẩn danh

Khái niệm

Hàm ẩn danh là hàm được tạo ra mà không cần đặt tên riêng để tái sử dụng nhiều nơi. Chúng thường được dùng trong các biểu thức ngắn, truyền vào hàm khác hoặc tạo hành vi tạm thời tại chỗ.

Ví dụ cơ bản

square = lambda number: number * number
print(square(5))
Func<int, int> square = number => number * number;
Console.WriteLine(square(5));
const square = (number) => number * number;
console.log(square(5));
#include <iostream>
#include <functional>
using namespace std;

int main() {
    auto square = [](int number) { return number * number; };
    cout << square(5) << endl;
    return 0;
}
const square = (number: number): number => number * number;
console.log(square(5));
package main

import "fmt"

func main() {
    square := func(number int) int {
        return number * number
    }
    fmt.Println(square(5))
}
fn main() {
    let square = |number: i32| number * number;
    println!("{}", square(5));
}

Khi nên dùng

  • Khi phần xử lý rất ngắn và chỉ dùng tại một vị trí.
  • Khi cần truyền một hành vi vào hàm khác như sắp xếp, lọc hoặc biến đổi dữ liệu.
  • Khi việc đặt tên riêng cho hàm không làm tăng thêm ý nghĩa.

Ghi chú theo ngôn ngữ

Thông tin</div>

Pascal truyền thống không có lambda hoặc closure theo nghĩa hiện đại. Các bài toán tương tự thường được xử lý bằng thủ tục, hàm thường hoặc callback theo cơ chế riêng của thư viện.

C không có hàm ẩn danh chuẩn trong ngôn ngữ lõi. Khi cần truyền hành vi, người ta thường dùng con trỏ hàm và dữ liệu đi kèm.

Lambda trong Python chỉ phù hợp với biểu thức ngắn. Nếu thân hàm có nhiều bước xử lý, nên dùng def để giữ mã rõ ràng.

C++ hỗ trợ lambda từ C++11 với cú pháp [capture](params) { body }. Có thể bắt biến từ phạm vi ngoài bằng cơ chế capture.

C# dùng biểu thức lambda (params) => body rất phổ biến với LINQ (xử lý dữ liệu) và sự kiện. Func<T,R>Action<T> là kiểu delegate chứa lambda.

JavaScript có arrow function (x) => x * x. Khác biệt quan trọng so với function thường: arrow function không có this riêng (kế thừa this từ phạm vi chứa nó). Rất phổ biến với map, filter, reduce.

TypeScript dùng arrow function giống JavaScript nhưng bổ sung cú pháp kiểu. Đây là cách tự nhiên nhất để viết hàm trục tiếp trong biểu thức.

Go có hàm ẩn danh (anonymous function) và closure. Hàm ẩn danh có thể được gán vào biến hoặc truyền trực tiếp như một đối số.

Rust dùng cú pháp |params| body cho closure. Closure có thể bắt giá trị từ môi trường xung quanh theo 3 cách khác nhau: bằng tham chiếu, tham chiếu mượn có thể thay đổi, hoặc lấy quyền sở hữu.

Kết luận

Hàm ẩn danh làm mã linh hoạt hơn khi xử lý các thao tác ngắn. Tuy nhiên, nên ưu tiên tính rõ ràng của mã hơn là cố rút gọn bằng mọi giá.

Bình luận