Swift - Custom operators - Part 2
swift
57
ios
48
operator
3
Male avatar

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

Swift - Custom operators - Part 2

=====
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

=====
Ở Part 1: https://kipalog.com/posts/Swift---Custom-operators---Part-1, mình đã giới thiệu cơ bản về operator và cách custom nó. Trong phần 2 này mình sẽ đi sau tìm hiểu thêm 1 số phần khác nâng cao hơn chút.

1. Generic Operators
Bây giờ mình muốn phép luỹ thừa apply cho toàn bộ các loại Integer. Code như sau, cũng khá dễ hiểu:

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

Chú ý đến Integer type constrain. Cái ràng buộc cần có bởi vì dòng code: có operator *= không phải loại nào cũng dùng được, phải conform Integer Type mới dùng được. Bây giờ ta test thử với các loại Integer khác nhau:

let unsignedBase: UInt = 2
let unsignedResult = unsignedBase ** exponent

let base8: Int8 = 2
let result8 = base8 ** exponent

let unsignedBase8: UInt8 = 2
let unsignedResult8 = unsignedBase8 ** exponent

let base16: Int16 = 2
let result16 = base16 ** exponent

let unsignedBase16: UInt16 = 2
let unsignedResult16 = unsignedBase16 ** exponent

let base32: Int32 = 2
let result32 = base32 ** exponent

let unsignedBase32: UInt32 = 2
let unsignedResult32 = unsignedBase32 ** exponent

let base64: Int64 = 2
let result64 = base64 ** exponent

Như vậy, nó đúng cho tất cả các loại integer: Int, UInt, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64 and UInt64. Int/ UInt/ Int8 là gì các bạn tự tìm hiểu thêm nha.

2. Precedence and associativity
Nếu chỉ có 2 giá trị thì khá đơn giản nhưng nếu là đoạn code sau thì sao:

2 * 2 ** 3 ** 3 // không thể compile

Swift không thể compile được nếu thiếu các thông tin sau đây:

  • Độ ưu tiên (precedence): Phép nào trước phép nào, nhân trước hay luỹ thừa trước.
  • Độ kết hợp (associativity): Từ trái qua phải trước hay từ phải qua trái trước.

Nếu không có 2 thông tin trên thì có 1 cách duy nhất để Swift hiểu và compile, đó là quăng vào dấu ngoặc đơn:

 2 * (2 ** (3 ** 2))

Để tránh khỏi sự phiền hà, ta chỉ cần define ra precedence group như sau:

precedencegroup ExponentiationPrecedence {
  associativity: right
  higherThan: MultiplicationPrecedence
}
infix operator **: ExponentiationPrecedence

Cái mà mình define ở trên là ưu tiên phép luỹ thừa trên phép nhân (MultiplicationPrecedence), và phép tính sẽ là từ phải sang trái (associativity: right). Bây giờ thì Swift có thể compile mà không cần thêm gì nữa.

Như vậy, qua 2 phần, mình đã giới thiệu thêm cho các bạn cụ thể về Custom Operators. Hi vọng các bạn có thêm được phần kiến thức bổ ích cho mình.

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

9 bài viết.
22 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
4 0
Autolayout và lifecycle trong IOS 1. Lý thuyết: Trước hết, mình xin nói về một vài lifecycle trong swift để mọi người nhớ lại. Một câu hỏi phổ b...
Bùi Khánh Duy viết hơn 2 năm trước
4 0
Male avatar
2 0
Swift Closure: Bài 1: Closure cơ bản ===== 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...
Bùi Khánh Duy viết hơn 2 năm trước
2 0
Male avatar
1 5
RxSwift Phần bổ sung Bài 1: Hot và Cold 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ủ...
Bùi Khánh Duy viết hơn 2 năm trước
1 5
Bài viết liên quan
White
2 3
Xin chào mọi người. Mình xin chia sẽ một UILabel Helper nhỏ dùng trong truờng hợp cần tính chiều cao của UILabel để xác định "Show More" button có ...
DonDinh viết hơn 5 năm trước
2 3
{{like_count}}

kipalog

{{ comment_count }}

bình luận

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


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
9 bài viết.
22 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á!