Swift - Custom operators - Part 1
swift
69
ios
54
operator
3
Male avatar

Bùi Khánh Duy viết ngày 30/06/2018

Swift - Custom operators - Part 1

=====
Updated ngày 30/06

Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog, mình mới dọn về nhà mới ở đây, thoải mái, đẹp đẽ rõ ràng hơn kipalog. Mong các bạn có thể theo dõi tại trang web của mình để cập nhật thêm nha

Mình mới viết một loạt bài về chủ đề Clean Architecture và Service Locator. Các bạn có thể theo dõi.
Page trên facebook ở đây: ở đây

=====
Trong phần này, các bạn sẽ được tự chế tạo operator cho riêng mình. Nó sẽ biểu diễn cho 1 loạt function phức tạp lặp đi lặp lại nhiều lần. Ví dụ nếu bạn có phép tính 2 nhân 2 nhân 2 v..v thì tại sao không có phép tính luỹ thừa cho gọn. Trước tiên, mình nên làm 1 type cố định rồi khi nào quen rồi mình mở rộng bằng cách dùng generic.

1. Lý thuyết về các loại toán tử:

a. Toán tử một ngôi (unary): được dùng với duy nhất 1 toán hạng hay một tiền tố. Chỗ này mình phân tích thêm chút, nó bao gồm:

  • Postfix: Những toán tử đứng sau, hay gặp nhất là a!, b?
  • Prefix: Những toán tử đứng trước ví dụ như !true, ++a

b. Toán tử hai ngôi (binary): được dùng với 2 toán hạng. Các toán tử +, -, x , % , hay toán tử so sánh ==, !== hay logic &&, || đều thuộc về phần này.

  • Infix là một tên gọi khác của toán tử 2 ngôi này, vì nó nằm giữa.

c. Toán tử ba ngôi (ternary): được dùng với 3 toán hạng. Chắc các bạn còn nhớ đến toán tử điều kiện ? chứ. ví dụ: (a == b ? true : false).

1.Ví dụ: Toán tử luỹ thừa
Đặt toán tử luỹ thừa là dạng toán từ mà mình tự custom, nên ta chọn đặt tên thoải mái. Cách đặt thường là sẽ kết hợp các ký tự đặt biết mà phải có ý nghĩa 1 chút. Ví dụ, luỹ thừa là nhiều phép nhân, nên ta đặt: ** hoặc các bạn đặt là ^ cũng được.

Swift không cho phép ta custom ternary operator

Cái ta có thể custom là các phần còn lại như prefix, postfix, infix. Phép luỹ thừa là cần đến 2 toán hạng nên ta dùng infix. Code như sau:

infix operator **

func **(lhs: Int, rhs: Int) -> Int {
  var result = lhs
  for _ in 2...rhs {
    result *= lhs
  }
  return result
}

infix: dạng type của operator cần custom
operator: keyword
**: cái mình muốn tạo ra
tiếp theo là func mà mình muốn định nghĩa cho phép nhân đó. Một lưu ý các bạn để ý đến đoạn result *= lhs, cũng là một phép nhân rồi gắn, kiểu kiểu như custom operator nhưng được Swift tạo ra trước đó.

Note: Mình sẽ dùng wildcard pattern để discard những giá trị loop bằng kỹ thuật "Pattern Matching". Các bạn xem thêm ở đây.

Bây giờ, test thử code:

let base = 2
let exponent = 2
let result = base ** exponent

2. Toán tử kết hợp với phép gắn:
Như mình đã lưu ý ở phần trên, thì mọi operator mình làm thì thường phải có thêm phần compound assignment (kết hợp luôn phép gắn). Xem phần code sau:

infix operator **=
func **=(lhs: inout Int, rhs: Int) {
  lhs = lhs ** rhs
}

Một trong những phần hay mình sẽ phân tích ở đây. Nếu như mình làm bình thường sẽ như ở trên, tức là var result -> xử lý code -> gán lại cho result. Nhưng ở đây mình sẽ dùng inout keyword. Inout là gì, cách dùng như thế nào, các bạn xem ở đây.

Như vậy, bằng việc dùng inout, ta lấy được giá trị sau cùng. Func sẽ thay đổi inout parameter trực tiếp bởi vì nó được truyền thông qua reference.

Đây là thành quả:

 var number = 2
number **= exponent

3. Thách đố nhỏ

Bây giờ mình muốn tạo 1 operator mà 2 argument truyền vào là string và số lần. Qua phép nhân đó, sẽ nhân số string lên n lần. Ví dụ:

let baseString = "abc"
let times = 5
var multipliedString = baseString ** times

Giúp mình với nhé ;)

Tiếp theo mình sẽ đi qua phần hai, những phần Advance hơn về Custom Operator.
Part 2: https://kipalog.com/posts/Swift---Custom-operators---Part-2

Tài liệu tham khảo: Ebook Swift_Apprentice_v2.0

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

Male avatar

Bùi Khánh Duy

29 bài viết.
11 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
4 3
RxSwift: Bài 1 Observable và Just, Of, From ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalo...
Bùi Khánh Duy viết 7 tháng trước
4 3
Male avatar
4 0
Autolayout và lifecycle trong IOS ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog, mình mớ...
Bùi Khánh Duy viết 5 tháng trước
4 0
Male avatar
2 3
RxSwift: Bài 2 Subscribing to observables ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog,...
Bùi Khánh Duy viết 7 tháng trước
2 3
Bài viết liên quan
White
11 4
(Link) (Link) (Link) Ở 2 phần tut trước, mình đã hướng dẫn khá chi tiết cách viết một ứng dụng camera có tích hợp chức năng nhận diện khuôn mặ...
HoangPH viết hơn 3 năm trước
11 4
Male avatar
0 0
RxSwift: Bài 6: RxCocoa (Part 4) Units ===== Updated ngày 30/06 Updated một chút: Vì những bất tiện và không rõ ràng về thông tin của kipalog, mì...
Bùi Khánh Duy viết 7 tháng trước
0 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
29 bài viết.
11 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!