Tìm hiểu về Generic trong Rust

Tram Ho

1. Giới thiệu

Với Rust, generics là một khái niệm sinh ra nhằm tránh việc trùng lặp code khi xử lý một logic cho nhiều kiểu dữ liệu khác nhau. Nghe vẫn hơi mơ hồ nhỉ. Chúng ta sẽ tìm hiểu chi tiết hơn ngay nhé.

Ví dụ bên dưới khá dễ hiểu, chúng ta sẽ đi tìm giá trị lớn nhất trong 1 mảng số nguyên.

Ví dụ thứ 2, chúng ta tìm giá trị lớn nhất của 2 mảng và in ra chúng. Code vẫn chạy đúng nhưng logic vòng lặp tìm giá trị lớn nhất bị lặp lại, trông rất cồng kềnh.

Ở ví dụ thứ 3, chúng ta sẽ chuyển logic tìm giá trị lớn nhất thành một hàm riêng và gọi lại khi cần thiết.

Qua 3 ví dụ trên, code đã dần dần được gọn và tối ưu hơn qua các bước sau:

  1. Xác định phần code trùng lặp
  2. Đưa các code trùng lặp thành 1 hàm riêng và chỉ định tham số đầu vào, giá trị trả về.
  3. Thay phần logic trùng lặp bằng lời gọi hàm.

Nếu hàm largest chúng ta dùng không chỉ cho kiểu dữ liệu i32 mà các kiểu dữ liệu khác nữa như char, float, … thì sao.  Chúng ta sẽ viết thêm hàm với tham số đầu vào là các kiểu dữ liệu cần xử lý. Nhưng có vẻ như thế thì logic code lại bị trùng lặp nhiều rồi. Đây là lúc chúng ta cần sử dụng đến generic

2. Các kiểu dữ liệu Generic (Generic Data Types)

Generic với hàm

Ở ví dụ dưới đây, chúng ta muốn tìm thêm ký tự lớn nhất trong 1 mảng các ký tự. Tuy logic y hệt như cách tìm giá trị lớn nhất trong 1 mảng số nguyên, nhưng giá trị đầu vào ở hàm largest_32 trước đó phải là kiểu i32. Ta đành phải tạo 1 hàm mới là largest_char. Đã đến lúc chúng ta dùng generic để tối ưu code hơn rồi !

Cú pháp khi sử dụng generic để định nghĩa hàm largest sẽ như sau:

T là tham số định nghĩa chung cho kiểu dữ liệu mà hàm largest được truyền vào. T là viết tắt của type, chúng ta có thể dùng các ký tự khác như U, A, B, C, Y, Z …, nhưng thường lựa chọn mặc định được quy ước là T.

Khi sử dụng tham số T ta, cần khai báo nó ngay sau tên hàm bằng cách đưa vào dấu <> để trình biên dịch hiểu rằng bạn đang sử dụng generic với tham số T.

Hàm largest sau khi sử dụng generic sẽ như sau:

Generic với struct

Chúng ta cũng có thể sử dụng generic với struct, cùng xem qua các ví dụ sau đây:

Generic với enum

Generic với methods

Chúng ta có thể sử dụng generic cho các implement methods của struc hay enum.

Lưu ý rằng chúng ta phải khai báo T ngay sau impl để có thể sử dụng T trên kiểu Point <T> và không phải lúc nào kiểu tham số generic được định nghĩa ở struct cũng sẽ giông như ở method của struct.

Lưu ý thêm: Dùng generic không làm ảnh hướng đến hiệu suất chương trình so với khi dùng các kiểu dữ liệu cụ thể.

Tài liệu tham khảo

Rust Programing Language

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo