Đây là nội dung khá hay và được ứng dụng nhiều trong lập trình Swift. Trước khi đi vào bài này, mình lưu ý là bạn cần nắm thật vững bài kiểu hàm. Bởi nội dung phần này có quan hệ khá mật thiết với hàm và kiểu hàm. Đầu tiên chúng ta thử tìm hiểu closure là gì đã nhé.
Closure là gì?
Thực ra thì closure cũng không quá xa lạ gì đâu bạn ạ. Closure đơn giản là một khối lệnh đặc biệt nhằm thực hiện một chức năng cụ thể nào đó. Bản chất của nó cũng gần tương tự hàm, hay có thể xem đây là một dạng hàm rút gọn. Chính vì vậy mà closure cũng có tham số và dữ liệu trả về tương tự hàm.
Nếu bạn đã từng học qua Objective-C hoặc C# thì bạn sẽ thấy nó tượng tự blocks hoặc lambas.
☞ Hàm là một trường hợp đặc biệt của Closure.
☞ Hàm là một dạng Closure có tên hoặc có thể nói Closure chính là một hàm nặc danh (không có tên).
Đọc qua những khái niệm này thì bạn đã mường tượng closure là gì chưa? Chắc vẫy chưa đâu nhỉ, nhưng bạn cũng đừng quá lo lắng bởi vì chúng ta mới chỉ bắt đầu thôi.
Khai báo
Trước khi trình bày cú pháp, thì một lần nữa mình lưu ý lại là bạn hãy ôn lại kiểu hàm nếu đã quên đi nhé. Bởi cú pháp của closure có mối quan hệ khá mật thiết với kiểu hàm đó bạn ạ. Sau đây là cú pháp khai báo:
Có lẽ nhìn cú pháp ở trên sẽ khá khó hiểu đối với bạn mới. Để cho dễ hiểu thì mình sẽ viết một ví dụ đơn giản như sau:
Trong ví dụ trên, mình xây dựng một closure có chức năng in ra màn hình câu “Hello, world”. Các bạn để ý nhé:
- Khai báo closure sẽ luôn đặt trong cặp dấu “{” “}“.
- Phần mình highlight, các bạn có nhận ra đó là gì không? Đó chính là kiểu hàm đó bạn ạ. Từ kiểu hàm này chúng ta có thể thấy rằng closure này không có tham số và cũng không trả giá trị nào ra ngoài cả.
Bạn đã hình dung ra closure là gì chưa? Để củng cố thêm kiến thức, mình làm tiếp 1 ví dụ nữa nhé:
Ví dụ này là xây dựng closure có chức năng tìm giá trị nhỏ nhất của 2 số nguyên a và b. Bạn hãy để ý những chỗ mình highlight và so sánh với ví dụ trước thử đi nhé. Trong ví dụ này, mình khai báo closure có 2 tham số đầu vào, đồng thời closure này cũng trả ra một số nguyên ra bên ngoài. Bạn thấy sao? Có tương tự khai báo một hàm không? Đến đây thì chắc bạn đã hiểu closure là gì rồi phải không nào?
Khối lệnh nặc danh
Về cơ bản thì những gì mình trình bày ở trên là xong về closure. Nhưng thực tế khi sử dụng thì nó có một số biến thể, và đây là một trong những biến thể đó.
Khối lệnh nặc danh chính là việc khai báo closure mà không cần đặt tên cho các tham số. Chúng ta chỉ cần định nghĩa khối lệnh chức năng của closure mà thôi. Do không đặt tên nên các tham số sẽ được truy xuất bằng chỉ số thứ tự $0, $1,…
Xét ví dụ sau:
Từ ví dụ trên, các bạn thấy rằng chúng ta khai báo biến min có kiểu hàm. Kiểu hàm này có 02 tham số đầu vào là số nguyên và có trả một số nguyên ra ngoài. Nhưng đây là khai báo biến nhé, còn closure chính là khối lệnh được gán đằng sau đó các bạn. Khối lệnh này không khai báo kiểu hàm nào cả mà thực hiện luôn chức năng. Trong trường hợp này chúng ta gọi đó là closure nặc danh, kiểu hàm của nó sẽ dựa vào kiểu hàm của biến min.
Ngầm định giá trị trả về
Đối với những khối lệnh nặc danh, chúng ta còn có thể rút gọn hơn một chút nữa. Bằng cách bỏ từ khóa return nếu khối lệnh chức năng của Closure chỉ có duy nhất một biểu thức.
Nếu bạn để ý ví dụ trên, thì khối lệnh nặc danh mà mình khai báo chỉ có duy nhất một biểu thức. Nhờ đó mình có thể rút gọn hơn một chút bằng cách bỏ luôn return, kết quả sẽ như thế này:
Tổng kết
Phần này mình đã trình bày cho các bạn closure là gì và cách thức khai báo sử dụng closure. Không quá nhiều ý để viết trong bài này nhưng closure lại rất hay được sử dụng trong lập trình Swift. Có thể rằng các bạn vẫn chưa thấy được sự hữu dụng của nó, đừng vội nhé chủ đề này còn dài và các bạn sẽ được ứng dụng trong những bài tập cụ thể ở những nội dung sau.