Hai năm trước, khi tôi bắt đầu với iOS, tôi không biết tuple là gì, tại sao và nơi tôi sẽ sử dụng chúng. Trong vài tuần sau đó, tôi nhận ra rằng tôi thực sự đang sử dụng chúng ở mọi nơi, tôi chỉ không biết điều đó.
Ví dụ nhỏ:
1 2 | func willDoNothing() {} |
Đôi khi thậm chí vô tình bạn chạy func mà không làm gì, và trình biên dịch nói gì về điều đó. Trình biên dịch return() một tuple trống.
Swift đang ánh xạ trả về void trong tuples.
Tuples không có một định nghĩa chính thức, không rõ ràng, nhưng dễ tạo và rất dễ sử dụng.
Tuy nhiên nó cũng có những nhược điểm, chúng không thể implement các method và protocol.
Và giống như mọi bộ khác, bạn không thể thay đổi loại của nó.
Đây là một ví dụ cơ bản:
1 2 3 4 | let client = (fullName: "SomeName", isActive: Bool, age: Int) // you will access elements like this fullNameTextField.text = client.fullName |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | let bankClient = (clientType: "Company", isPremiumClient: true) switch bankClient { case let(type, false): print("client type is (type) and it is not a premium client" ) default: break } // hoặc bạn có thể bỏ qua các yếu tố của tuple switch bankClient { case let (type, _): print("client type is (type)" ) default: break } |
Đây là một chủ đề nâng cao với closure:
Ngay cả khi bạn không thể thêm phương thức vào tuple, bạn có thể thêm closure
1 2 3 4 | let client = (name: "John", bankNumber: "01234567890", cardType: "Visa", withdrawalAmount: { (cash: Double) in print("amount (cash)") }) |
Thành thật mà nói, tôi không nhớ ngay cả đã làm điều này trong các tình huống thực tế, nhưng tôi biết điều này sẽ hiệu quả, nhưng có một vấn đề với closure và tuple với nhau.
Bạn không thể truy cập một số yếu tố theo cách này:
1 2 3 | print("my name is (client.name, client.withdrawalAmount)") // mã này sẽ không được biên dịch |
Vậy chúng được sử dụng nhiều nhất ở đâu?
Giống như trong các bài viết khác đề cập đến chủ đề này, tôi cũng sẽ nói như vậy:
Khi bạn cần một func sẽ trả về nhiều loại giá trị.
Nhưng điều đó có nghĩa là gì, trong thực tế. Có lẽ bạn sẽ không viết bất cứ điều gì như thế này:
1 2 3 4 | func someClient() -> (name: String, age: Int, havePremiumAccount: Bool) { return ("John", 27, true) } |
Nhưng trong ít nhất 50% ứng dụng, bạn sẽ có một cái gì đó như thế này:
1 2 3 4 5 6 7 8 9 10 | func fetchBankClient(id: Int) -> (client: Client, havePremiumAccount: Bool, accountNumber: String) { /// } let client = fetchBankClient(id: 1054) // sau đó bạn có thể sẽ cập nhật giao diện người dùng với dữ liệu này hoặc tạo một số lệnh gọi API để gửi một số dữ liệu đến máy chủ. Một cái gì đó như thế này: if client.havePremiumAccount == true { showFastCreditView = true } |
Điều này thật tuyệt, nhưng swift thậm chí còn có cách tốt hơn để làm điều này
1 2 3 4 5 | let (client, havePremiumAccount, accountNumber) = fetchBankClient(5) // trong swift này được gọi là destructuring tuple. // Bây giờ có 3 biến mới mà bạn có thể truy cập dễ dàng hơn. // Và nó có vẻ dễ đọc hơn. |
Tóm tắt điều này, trong hầu hết các trường hợp, bạn sẽ sử tuple làm loại kết quả trả về của lệnh call API, escaping closure.
1 2 | func getClients(objectToPass: Object, completion:@escaping (SomeType, Error) → ReturnType) |
Typealias và tuples:
Tuple rất tốt cho chức năng này, việc viết các hàm có bộ dữ liệu là kiểu trả về sẽ dễ dàng hơn nhiều nếu bạn thực hiện chúng như thế này.
Tuples có thể rất dài và có thể lặp lại nhiều lần trong cùng một method.
Ví dụ:
1 2 3 4 | typealias UserDestination = (destination:(latitude: Double, longitude: Double)) func showOnMap() -> UserDestination { } |
Ví dụ thực tế:
1 2 3 4 5 6 | protocol URLSessionProtocol { typealias DataTaskResult = (Data?, URLResponse?, Error?) -> () func dataTask(request: URLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTask } |
Một cái gì đó khác nữa mà tôi có thể đề cập là một tuple tùy chọn:
1 2 3 4 5 | let client : (String, Bool)? = ("Milos", true) // this tuple is optional tuple let client: (String, Bool?) = ("Milos", nil) // this tuple have optional elements |
Cuối cùng là mẹo kiểm tra phỏng vấn có thể được thực hiện với tuple và chắc chắn bạn sẽ nhận được nhiều điểm hơn
Chúng ta đều biết về thử nghiệm fizzbuzz. Bạn sẽ nhận được một dãy số và bạn sẽ cần kiểm tra số nào chia hết cho hai số còn lại, trong hầu hết các trường hợp là 3 và 5.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | let numbers = [Int]() for i in 1...100 { numbers.append(i) } func fizzBuzz(number: Int) { switch (number % 3 == 0, number % 5 == 0) { case (true, false): print("Fizz") case (false, true): print("Buzz") case (true, true): print("FizzBuzz") case (false, false): return } } for i in numbers { fizzBuzz(i) } |
Phần kết luận
Tôi hy vọng bạn thích điều này, nếu có bất cứ điều gì không rõ ràng về điều này, hoặc bạn có một cái gì đó tuyệt vời hoặc thực sự nâng cao về chủ đề này xin vui lòng bình luận.
Nguồn: Medium