- vừa được xem lúc

Equatable trong Swift

0 0 18

Người đăng: Phạm Thế Hùng

Theo Viblo Asia

Equatable

Các giá trị tuân theo protocol Equatable có thể được đánh giá về sự bằng nhau hoặc không bằng nhau. Sự phù hợp với Equatable yêu cầu triển khai toán tử bằng nhau (==).

Ví dụ, hãy xem xét struct Binomen sau:

struct Binomen { let genus: String let species: String
} let ? = Binomen(genus: "Canis", species: "lupus")
let ? = Binomen(genus: "Ursus", species: "arctos")

Chúng ta có thể cho value phù hợp với Equatable thông qua một phần extension, implement method cho toán tử == như sau:

extension Binomen: Equatable { static func == (lhs: Binomen, rhs: Binomen) -> Bool { return lhs.genus == rhs.genus && lhs.species == rhs.species }
} ? == ? // true
? == ? // false

Thật dễ dàng, phải không?

Thực ra, nó thậm chí còn dễ dàng hơn thế - kể từ Swift 4.1, trình biên dịch có thể tự động tổng hợp sự phù hợp cho các struct mà các thuộc tính được lưu trữ của chúng đều có các kiểu là Equatable. Chúng ta có thể thay thế tất cả mã trong extension bằng cách chỉ cần sử dụng Equatable trong khai báo Binomen:

struct Binomen: Equatable { let genus: String let species: String
} ? == ? // true
? == ? // false

Lợi ích của Equatable

Equatability không chỉ sử dụng toán tử == mà còn có thể coi nó là một value, như việc nó được tìm thấy trong một tập hợp và được so khớp trong một câu lệnh switch.

[?, ?].contains(?) // true func commonName(for binomen: Binomen) -> String? { switch binomen { case ?: return "gray wolf" case ?: return "brown bear" default: return nil }
}
commonName(for: ?) // "gray wolf"

Equatable cũng là một yêu cầu để tuân thủ Hashable, một kiểu quan trọng khác trong Swift.

Tất cả điều này để nói rằng nếu một kiểu có ngữ nghĩa tương đương - nếu hai giá trị của kiểu đó có thể được coi là bằng nhau hoặc không bằng nhau - thì nó phải tuân theo Equatable.

Giới hạn của Automatic Synthesis

Thư viện tiêu chuẩn Swift và hầu hết các framework trong Apple SDK đều làm rất tốt việc áp dụng Equatable cho các type có ý nghĩa. Trên thực tế, bạn khó có thể gặp phải tình huống mà automatic synthesis không hoạt động.

Thay vào đó, trở ngại phổ biến nhất đối với tổng hợp tự động liên quan đến các bộ giá trị. Hãy xem xét loại Trinomen này:

struct Trinomen { let genus: String let species: (String, subspecies: String?) // ?
} extension Trinomen: Equatable {}
// ? Type 'Trinomen' does not conform to protocol 'Equatable'

các tuple không phải là nominal type, vì vậy chúng không thể phù hợp với Equatable. Nếu bạn muốn so sánh hai trinomina cho bằng nhau, bạn phải viết mã tuân thủ cho Equatable.

Conditional Conformance to Equality

Ngoài tính năng automatic synthesis của Equatable, Swift 4.1 còn bổ sung một tính năng quan trọng khác: conditional conformance.

Để minh họa điều này, hãy xem xét type chung sau đại diện cho một số lượng của một cái gì đó:

struct Quantity<Thing> { let count: Int let thing: Thing
}

Quantity có thể conform theo Equatable không? Chúng ta biết rằng các số nguyên là tương đương, vì vậy nó thực sự phụ thuộc vào Thing mà chúng ta đang nói đến.

Conditional conformance mà Swift 4.1 cho phép chúng ta thực hiện là tạo một phần extension trên một kiểu có mệnh đề điều kiện. Chúng ta có thể sử dụng điều đó ở đây để diễn đạt theo chương trình rằng _ “một số lượng của một sự vật là tương đương nếu bản thân sự vật đó là tương đương”:

extension Quantity: Equatable where Thing: Equatable {}

Và chỉ với tuyên bố đó, Swift có mọi thứ cần thiết để tổng hợp sự phù hợp có điều kiện của Equatable, cho phép chúng tôi thực hiện những việc sau:

let oneHen = Quantity<Character>(count: 1, thing: "?")
let twoDucks = Quantity<Character>(count: 2, thing: "?")
oneHen == twoDucks // false

Cũng có thể áp dụng cho Array nếu phần tử trong Array đó conform theo Equatable

[?, ?] == [?, ?] // true

Equality by Reference

Đối với các loại tham chiếu, khái niệm bình đẳng trở nên đồng nhất với identity. Có nghĩa là hai struct Name có cùng giá trị sẽ bằng nhau, nhưng hai Object Person có thể có cùng tên và vẫn là những người khác nhau.

Đối với các loại đối tượng tương thích với Objective-C, toán tử == đã được cung cấp từ phương thức isEqual:

import Foundation class ObjCObject: NSObject {} ObjCObject() == ObjCObject() // false

Đối với các kiểu tham chiếu Swift (nghĩa là các lớp), sự bình đẳng có thể được đánh giá bằng cách sử dụng identity equality operator (===):

class Object: Equatable { static func == (lhs: Object, rhs: Object) -> Bool { return lhs === rhs }
} Object() == Object() // false

Điều đó nói rằng, ngữ nghĩa tương đương cho các loại tham chiếu thường không đơn giản như kiểm tra identity equality, vì vậy trước khi bạn thêm Equatable vào tất cả các lớp của mình, hãy tự hỏi liệu làm như vậy có thực sự hợp lý hay không.

Bài viết đến đây là hết. Nguồn: https://nshipster.com/equatable-and-comparable/#the-limits-of-automatic-synthesis

Bình luận

Bài viết tương tự

- vừa được xem lúc

Swift: Tạo custom phép toán tử (Operator) của riêng bạn!

Swift cho phép bạn tạo các toán tử có thể tùy chỉnh của riêng bạn. Điều này đặc biệt hữu ích khi bạn xử lý các loại dữ liệu của riêng mình. Operator Types in Swift. Có năm loại toán tử chính trong Swift.

0 0 56

- vừa được xem lúc

Code ngắn gọn hơn với OptionSet trong Swift

. Nếu bạn muốn biết cách xử lý với Bitmasks trong Swift hay là bạn đã từng nghe đến OptionSet chưa? Bài viết này sẽ giúp bạn hiểu hơn về điều đó . 1.

0 0 41

- vừa được xem lúc

Chương 6 Protocol oriented programming.

Cuốn sách này là về lập trình hướng protocol. Khi Apple thông báo swift 2 ở WWDC 2015.

0 0 48

- vừa được xem lúc

Ví dụ về UIActivityViewController

Trên iOS, UIActivityViewController cung cấp giao diện thống nhất để người dùng chia sẻ và thực hiện các hành động trên văn bản, hình ảnh, URL và các mục khác trong ứng dụng. let string = "Hello, world!". let url = URL(string: "https://nshipster.com").

0 0 58

- vừa được xem lúc

Quản lý self và cancellable trong Combine.

. . Công việc quản lý bộ nhớ memory management thường trở nên phức tạp khi chúng ta thực hiện các tác vụ bất đồng bộ asynchronous vì chúng ta thường phải lưu giữ một số object nằm ngoài scope mà object được define trong khi vẫn phải đảm bảo được việc giải phóng object đó được thực hiện đúng quy trìn

0 0 41

- vừa được xem lúc

[SWIFT] Sử dụng Dependency Injection với Storyboards

1. Lời mở đầu:.

0 0 42