Hàm nhận input, làm gì đó, tạo output. Hàm có signature và body. Nếu cho cùng input vào hàm thì luôn ra cùng output. Đó là định nghĩa ngắn gọn function.
Giờ nói sâu hơn về hàm bằng cách nhìn gần hơn. Khám phá higher-order functions trong Swift. Hàm nhận hàm khác làm input hoặc trả về hàm gọi là higher order function.
Trong Swift, chúng ta chơi với map, filter, reduce hàng ngày. Dùng các hàm này như phép màu. Lúc này có thể chưa hiểu gì xảy ra behind the scenes. Map, Filter, Reduce hoạt động qua ý tưởng và approach của functional programming. Dù Swift không phải pure functional language, nhưng cho phép làm functional things.
Giờ xem từng cái background của chúng. Trước implement basic version cho data type cụ thể, sau implement generic version.
Map Function
Giả sử có array integer, cần hàm trả về array mới sau khi cộng delta value vào mỗi element array gốc. Dễ viết hàm dùng for loop đơn giản:
Cần hàm khác trả array mới nhân đôi mỗi element array gốc. Triển khai như sau:
Nhìn hai hàm trên, thấy chúng cơ bản làm cùng việc. Chỉ functionality bên trong for loop khác. Cả hai nhận Integer array input, transform mỗi element dùng for loop, trả array mới. Vậy chính là transform mỗi element thành thứ mới.
Vì Swift support higher-order functions, viết hàm nhận array integer, transform function input, trả array mới áp dụng transform function cho mỗi element array gốc.
Vẫn có vấn đề: chỉ trả integer array. Nếu yêu cầu convert input integer array thành string array, không làm được với hàm này. Cần generic function làm việc cho bất kỳ type.
Triển khai generic function trong Array extension như sau:
- Khai báo map function trong Array Extension dùng generic type T.
- Hàm nhận function kiểu (Element) → T input
- Khai báo result array rỗng giữ data type T bên trong hàm.
- Implement for loop lặp qua self và gọi transform function convert element thành type T
- Append giá trị convert vào result array
Đó là cách map function hoạt động trong Swift. Nếu implement map function, sẽ implement như trên. Vậy cơ bản, nó không làm magic gì trong array — chúng ta dễ dàng tự định nghĩa hàm.
Filter Function
Giả sử array integer, muốn giữ chỉ số chẵn. Implement dùng for loop đơn giản:
Lại nói, array string tên file class project, muốn giữ chỉ file .swift. Cũng làm với single loop:
Nhìn kỹ implementation hai hàm trên, hiểu chúng làm cùng việc — chỉ data type khác cho hai array. Generalize bằng generic filter function, nhận array và function input, tùy output includeElement function quyết định có add element vào result array không.
Reduce Function
Giả sử array integer, muốn implement hai hàm trả sum và product của element. Implement dùng for loop đơn giản:
Thay vì array integer, giả sử array string, muốn concatenate tất cả element:
Ba hàm cơ bản làm cùng việc. Nhận array input, khởi tạo result variable, iterate array, update result variable.
Từ đây implement generic function cho tất cả. Cần initial value của result variable và function update variable mỗi iteration.
Implement generic function định nghĩa sau:
Implementation trên generic cho bất kỳ input array kiểu [Element]. Compute result kiểu T. Cần initial value kiểu T gán cho result variable. Sau đó, cần function kiểu (T, Element) → T dùng trong for loop mỗi iteration update result variable.