Một hàm nhận một số đầu vào, thực hiện điều gì đó với nó và tạo ra một đầu ra. Một hàm có một chữ ký và một phần nội dung. Nếu bạn cung cấp cùng một đầu vào cho một hàm thì bạn luôn nhận được cùng một đầu ra. Tóm lại, đó là định nghĩa cho chức năng .
Bây giờ chúng ta sẽ nói nhiều hơn về các hàm bằng cách tìm hiểu kỹ hơn về chúng. Chúng ta sẽ khám phá các hàm bậc cao trong Swift. Một hàm nhận một hàm khác làm đầu vào hoặc trả về một hàm được gọi là chức năng đặt hàng cao hơn .
Trong Swift, chúng tôi chơi với bản đồ, bộ lọc, thu nhỏ Hằng ngày. Khi chúng ta sử dụng các chức năng này, nó có vẻ như là ma thuật. Tại thời điểm này, bạn có thể không biết những gì đang diễn ra ở hậu trường. Lập bản đồ, Lọc và Giảm bớt công việc thông qua các ý tưởng và cách tiếp cận của lập trình chức năng. Mặc dù Swift không phải là một ngôn ngữ chức năng thuần túy, nhưng nó cho phép bạn thực hiện các chức năng.
Bây giờ chúng ta hãy xem xét từng thứ một về những gì đang xảy ra trong nền cho họ. Trước tiên, chúng tôi sẽ triển khai các phiên bản cơ bản của các hàm này cho một số kiểu dữ liệu cụ thể, sau đó chúng tôi sẽ cố gắng triển khai một phiên bản chung.
Hàm bản đồ
Giả sử chúng ta có một mảng các số nguyên và chúng ta cần viết một hàm trả về một mảng mới sau khi thêm một số giá trị delta vào mỗi phần tử của mảng ban đầu. Chúng ta có thể dễ dàng viết một hàm cho điều này bằng cách sử dụng một vòng lặp for đơn giản như sau:
Bây giờ chúng ta cần một hàm khác trả về một mảng mới bằng cách nhân đôi từng phần tử của mảng ban đầu. Đối với điều này, chúng tôi có thể triển khai nó như sau:
Nếu chúng ta nhìn vào hai chức năng trên, chúng ta có thể thấy rằng về cơ bản chúng đang làm những việc giống nhau. Chỉ có chức năng bên trong vòng lặp for là khác. Cả hai đều lấy một Số nguyên mảng làm đầu vào, biến đổi từng phần tử bằng cách sử dụng vòng lặp for và trả về một mảng mới. Vì vậy, về cơ bản, điều chính là chuyển đổi mỗi phần tử thành một cái gì đó mới.
Vì Swift hỗ trợ các hàm bậc cao hơn, chúng ta có thể viết một hàm sẽ nhận một mảng số nguyên, biến đổi hàm làm đầu vào và trả về một mảng mới bằng cách áp dụng hàm biến đổi cho từng phần tử của mảng ban đầu.
Tuy nhiên, có một vấn đề ở trên:nó chỉ trả về một mảng số nguyên. Ví dụ:nếu chúng ta có yêu cầu chuyển đổi mảng số nguyên đầu vào thành mảng chuỗi, thì chúng ta không thể thực hiện điều đó với hàm này. Để làm được điều đó, chúng ta cần viết một hàm chung hoạt động cho bất kỳ kiểu nào.
Chúng ta có thể triển khai một hàm chung trong phần mở rộng Mảng như thế này:
- Khai báo một hàm bản đồ trong Tiện ích mở rộng mảng hoạt động với kiểu chung T .
- Hàm nhận một chức năng thuộc loại (Phần tử) -> ; T là đầu vào
- Khai báo một mảng kết quả trống chứa T nhập dữ liệu bên trong hàm.
- Triển khai một vòng lặp for tự lặp lại và gọi hàm biến đổi để chuyển đổi phần tử thành kiểu T
- Nối giá trị đã chuyển đổi vào mảng kết quả
Đây là cách bản đồ hàm hoạt động trong Swift. Nếu chúng tôi cần triển khai bản đồ chức năng , sau đó chúng tôi sẽ thực hiện nó như trên. Vì vậy, về cơ bản, nó không làm cho bất kỳ điều kỳ diệu nào xảy ra trong một mảng - chúng ta có thể dễ dàng tự định nghĩa hàm.
Chức năng Bộ lọc
Giả sử chúng ta có một mảng các số nguyên và chúng ta chỉ muốn giữ lại các số chẵn trong mảng. Chúng ta có thể thực hiện điều này bằng cách sử dụng vòng lặp for đơn giản:
Bây giờ, một lần nữa, giả sử chúng ta có một mảng chuỗi đại diện cho tên tệp lớp của một dự án và chúng ta chỉ muốn giữ lại . nhanh chóng các tập tin. Điều này cũng có thể được thực hiện với một vòng lặp như sau:
Nếu chúng ta xem xét kỹ việc thực hiện hai hàm trên, thì chúng ta có thể hiểu rằng về cơ bản chúng thực hiện cùng một việc - chỉ có kiểu dữ liệu là khác nhau đối với hai mảng. Chúng ta có thể tổng quát hóa điều này bằng cách triển khai một hàm lọc chung, lấy một mảng và một hàm làm đầu vào và tùy thuộc vào kết quả đầu ra của includeElement , nó quyết định có thêm phần tử vào mảng kết quả hay không.
Giảm chức năng
Giả sử chúng ta có một mảng các số nguyên và chúng ta muốn thực hiện hai hàm trả về tổng và tích của các phần tử. Chúng ta có thể thực hiện điều này bằng cách sử dụng vòng lặp for đơn giản:
Bây giờ thay vì có một mảng các số nguyên, giả sử chúng ta có một mảng các chuỗi và chúng ta muốn nối tất cả các phần tử trong mảng:
Về cơ bản, cả ba chức năng đều thực hiện cùng một chức năng. Chúng lấy một mảng làm đầu vào, khởi tạo một biến kết quả, lặp qua mảng và cập nhật biến kết quả.
Từ đây, chúng ta có thể triển khai một hàm chung sẽ hoạt động cho tất cả. Để làm điều này, chúng ta cần giá trị ban đầu của biến kết quả và hàm để cập nhật biến đó trong mỗi lần lặp.
Vì vậy, chúng ta có thể triển khai hàm chung với định nghĩa sau:
Việc triển khai ở trên là chung cho bất kỳ mảng đầu vào nào thuộc loại [Phần tử]. Nó sẽ tính toán kết quả thuộc loại T . Để hoạt động, nó cần giá trị ban đầu thuộc loại T để gán cho một biến kết quả. Sau đó, nó cần một hàm thuộc loại (T, Element) -> T sẽ được sử dụng bên trong vòng lặp for trong mỗi lần lặp để cập nhật biến kết quả.