Nạp chồng toán tử là một trong những tính năng rất mạnh của bất kỳ ngôn ngữ lập trình nào, do đó Apple đã quyết định cho tính năng này vào trong Swift. Bằng cách sử dụng nó, bạn có thể dễ dàng tạo ra những trường hợp kỳ cục ví dụ như làm cho toán tử trừ (“-“) thành cộng các số, hay là chia (“/”) thì lại thành nhân các số. Tuy nhiên chắc chắn đó không phải là điều bạn thực sự muốn làm khi sử dụng toán tử này đâu.

Thử thách

Trong phần hướng dẫn này, bạn có một bài tập đơn giản như sau: mở rộng chức năng cơ bản của toán tử nhân dùng cho các số sao cho các chuỗi cũng có thể dùng được. Ở đây, bạn sẽ sử dụng toán tử nối chuỗi, bạn có thể hình dung bài này như sau:

Trước khi bắt tay vào code, hãy nghĩ xem bạn sẽ giải quyết bài này như thế nào và trình tự sẽ làm là gì. Còn đây là cách tôi sẽ làm:

  • Tạo biến kết quả, khởi tạo giá trị đầu tiên – chuỗi mặc định
  • Chạy vòng từ 2 cho tới số lần nối chuỗi và mỗi vòng lặp chỉ thực hiện một lệnh gán chuỗi và kết quả.
  • In kết quả

Về cơ bản thuật toán là như thế, bây giờ đến phần thực hiện

Nạp chồng toán tử cơ bản

nạp chồng toán tử

Hãy bật Xcode lên và mở playground. Bạn hãy xóa các code cũ trong đó đi và thêm mẫu hàm toán tử nhân như sau:

Hàm này có 2 tham số – toán hạng bên trái kiểu String và toán hạng bên phải kiểu Int – vào kiểu trả về là String.

Có 3 bước bạn sẽ làm trong phần thân hàm. Đầu tiên, tạo biến kết quả và khởi tạo giá trị – đó là đối số kiểu chuỗi của hàm:

Tiếp theo chạy vòng lặp từ 2 cho tới đối số Int với kiểu vòng lặp “for in”  như sau:

Chú ý: bạn để biến chạy trong vòng lặp là gạch dưới “_” do bạn không cần sử dụng đến giá trị của nó – tìm hiểu thêm về vòng lặp ở đây.

Trong vòng lặp, bạn chỉ thực hiện đúng một lệnh update kết quả với giá trị chuỗi:

Cuối cùng trả về kết quả:

Bây giờ, chúng ta đã có thể sử dụng toán tử này:

Thế là xong. Tuy nhiên có một vấn đề khác là chúng ta chỉ có thể sử dụng toán tử này để nhân chuỗi. Còn các kiểu khác thì sao. Hãy cùng giải quyết vấn đề này với các toán tử generic.

Toán tử Generic

nạp chồng toán tử

Các kiểu generic mặc định là không hoạt động với các toán tử, do đó bạn cần sử dụng protocol. Thêm hàm nguyên mẫu sau vào playground:

Tiếp đến, thêm nguyên mẫu hàm toán tử gán giá trị cộng vào protocol:

Hàm này có cả hai toán hạng trái, phải thuộc kiểu Self, đây là một cách để thể hiện chúng là bất cứ  kiểu nào thực hiện protocol. Toán hạng trái được đánh dấu là inout do giá trị của nó được thay đổi và trả lại từ hàm.

Một cách khác mà bạn có thể định nghĩa nguyên mẫu hàm toán tử cộng :

Hàm này có cả toán hạng bên trái và phải thuộc kiểu Self và trả về kết quả cộng thuộc kiểu Self. Trong trường hợp này, bạn không cần sử dụng tên tham số inout nữa.

Tiếp đến, tạo extensions cho các kiểu String, Int, Double, Float mà thực hiện protocol “Type”

Chú ý, việc thực hiện các extension là rỗng bởi vì chúng ta không muốn thêm giá nào vào các kiểu mặc định này. Chúng đơn giản được tạo ra để phù hợp với protocol.

Bây giờ thêm nguyên mẫu hàm toán tử nhân vào playground:

Hàm này có 2 tham số: toán hạng trái thuộc kiểu T và toán hạng phải thuộc kiểu Int, giá trị trả về là kiểu T. Bạn sử dụng giới hạn kiểu để làm kiểu generic “T” phù hợp với protocol “Type”, do đó, nó hiểu được toán tử gán cộng.

Chú ý: Bạn cũng có thể định nghĩa giới hạn kiểu với từ khóa “where” – cách này dài hơn cách trên:

Việc thực hiện hàm này cũng giống hệt như trường hợp trước:

Chú ý: Bạn cũng có thể sử dụng toán tử cộng – nếu thế, hãy đảm bảo thêm nguyên mẫu hàm của nó vào protocol.

Bây giờ hãy thử thực hiện các toán tử generic:

Có một vấn đề ở đây: bạn đang sử dụng toán tử nhân chuẩn. Nó có thể gây ra một chút lẫn lộn. Tốt hơn là chúng ra thay đổi nó thành các toán tử khác. Bây giờ hãy xem chúng ta có thể sửa lại điều này bằng các toán tử custom như thế nào.

Các toán tử Custom

nạp chồng toán tử

Hãy thêm dòng sau vào playground để bắt đầu:

Chú giải:

  1. Tên toán tử nhân custom: **
  2. Kiểu của nó là infix do do nó là toán tử nhị phân với 2 toán hạng
  3. Nó đánh giá từ trái sang phải, do đó có left associativity
  4. Độ ưu tiên của nó là 150 – giống như toán tử nhân chuẩn

Chú ý: Bạn có thể đọc thêm về độ ưu tiên toán tử và associativity tại đây.

Nguyên mẫu của hàm toán tử custom tương tự như nguyên mẫu hàm toán tử chuẩn – chỉ khác tên:

Các bước thực hiện trong hàm cũng giống hệt như lần trước:

Sau đây là sử dụng toán tử custom:

Bây giờ còn một vấn đề nữa – phiên bản toán tử hỗn hợp cho toán tử nhân custom này chưa được định nghĩa, chúng ta sẽ tiếp tục ở phần sau:

Toán tử hỗn hợp

nạp chồng toán tử

Kiểu toán tử hỗn hợp này có độ ưu tiên và associativity giống hệt như trường hợp trước, chỉ khác tên:

Tiếp đến thêm, nguyên mẫu hàm toán tử hỗn hợp vào playground:

Hàm này không có kiểu trả về, do nó có toán hạng trái được đánh dấu là: “inout”

Nội dung của hàm này chỉ có một dòng sau: (sử dụng toán tử custom được định nghĩa lúc trước để trả về kết quả nhân)

Giờ là sử dụng toán tử này như sau:

Thế là xong – rất đơn giản phải không nào.

Kết luận

Nạp chồng toán tử khi được sử dụng với sự cẩn trọng có thể trở thành công cụ rất mạnh – tôi hy vọng bạn có thể tự tìm cách sử dụng chúng cho dự án của riêng mình.

Tham khảo thêm, bạn có thể tải file Playground trên GitHub. Tôi đã thử code này trên Xcode 7.3 và Switft 2.2.

Nguồn bài viết.

Bạn nghĩ thế nào về hướng dẫn này và nạp chồng toán tử? Hãy để lại comment phía dưới nhé!

Gramy via TechMaster 

LEAVE A REPLY