12/08/2018, 13:12

Tìm hiểu về Generics

** Generics là gì ?** Hiểu một cách nôm na đơn giản nhất, generic programming là việc bạn viết các function và kiểu dữ liệu mà không định nghĩa trước ra các loại dữ liệu sẽ sử dụng. Một ví dụ đơn giản nhất mà bạn có thể bắt gặp đó là kiểu Array trong Swift. Một Array có thể chứa các kiểu dữ ...

** Generics là gì ?**

Hiểu một cách nôm na đơn giản nhất, generic programming là việc bạn viết các function và kiểu dữ liệu mà không định nghĩa trước ra các loại dữ liệu sẽ sử dụng.

Một ví dụ đơn giản nhất mà bạn có thể bắt gặp đó là kiểu Array trong Swift. Một Array có thể chứa các kiểu dữ liệu khác nhau, từ String, Int, NSObject cho tới AnyObject. Và dù có sử dụng kiểu dữ liệu nào thì hành vi của Array cũng là như nhau.

Cách tiếp cận này giúp giản lược rất nhiều công sức, thay vì bạn phải viết từng hàm khác nhau cho từng kiểu dữ liệu khác nhau. Giờ đây ta chỉ cần viết một lần.

** Thử với Playground ** Để bắt đầu, bạn hãy mở một file Playground bằng Xcode và bắt đầu những dòng code sau :

func adderInt(x: Int, _ y: Int) -> Int {
  return x + y
}

Hàm adderInt thực hiện một nhiệm vụ là cộng hai giá trị kiểu Int được truyền vào và trả về một giá trị có kiểu Int

Giờ giả sử nếu bạn cần phải cộng hai giá trị có kiểu Double, bạn sẽ viết thêm một hàm thứ hai như sau:

func adderDouble(x: Double, _ y: Double) -> Double {
  return x + y
}

Vậy phải làm sao để ta không cần phải viết tới hai hàm, hay thậm chí 5 hàm nếu bạn muốn sử dụng cho cả các kiểu giá trị khác nữa ? Đây là lúc ta cần tới Generics Đến với chữ T thần thánh.

** Generics Function** Để tạo ra một hàm Generic, ta sẽ viết như sau:

func exampleFunction<T>(var1 : T, var2 : T) { }

Tất nhiên bạn không nhất thiết phải dùng chữ T , nhưng tôi thấy nhiều người dùng nên tôi cũng dùng chữ cái này. chữ T ở đây đóng vai trò là một placeholder, đại diện cho kiểu dữ liệu mà hàm sẽ sử dụng. Bạn truyền bất cứ kiểu dữ liệu nào vào, T sẽ đại diện cho kiểu dữ liệu đó. Như vậy hàm ở trên sẽ viết thành :

func adder<T>(x : T, y : T) -> T { return x + y }

** Generics Data Structure** Ngoài việc viết thành function, ta cũng có thể tạo ra các kiểu Data Structure với Generics ví dụ ta tạo một kiểu struct như sau :

struct IntStack {
 var items = [Int]()
 mutating func push(item : Int) {
	items.append(item)
 }
 mutating func pop() -> Int {
	return items.removeLast()
}
}

Kiểu Generics của nó như sau:

struct IntStack<T> {
 var items = [T]()
 mutating func push(item : T) {
	items.append(item)
}
 mutating func pop() -> T {
	return items.removeLast()
}
}

MỘt vài cái mơí trong Generics Swift 2.0 Subclassing Generics Classes

 Class Box<T>

Ta có thể subclass lại như sau :

class Gift<T>: Box<T> {
}

class StringBox: Box<String> {
}

Enums với Generic Associated Values

enum Result<ValueType, ErrorType> {
  case Success(ValueType)
  case Failure(ErrorType)
}

Kiểu define Generics trên chẳng hạn, rất hữu ích trong việc xử lý response của một network request.

0