Two years ago, when I started with iOS, I didn’t know what tuples were, why and where I would use them. Over the next few weeks, I realized that I was really using them everywhere, I just didn’t know it.
Small example:
1 2 | func willDoNothing() {} |
Sometimes even you accidentally run func with nothing, and the compiler says nothing about that. The compiler return () has an empty tuple.
Swift is mapping to return void in tuples.
Tuples does not have a definitive, unclear definition, but is easy to create and easy to use.
However, it also has disadvantages, they cannot implement methods and protocols. And like every other set, you can’t change its type.
Here is a basic example:
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 } |
This is an advanced topic with closures:
Even if you cannot add methods to the tuple, you can add closures
1 2 3 4 | let client = (name: "John", bankNumber: "01234567890", cardType: "Visa", withdrawalAmount: { (cash: Double) in print("amount (cash)") }) |
To be honest, I don’t remember even doing this in real situations, but I know this will work, but there’s a problem with closures and tuples together. You cannot access some elements in this way:
1 2 3 | print("my name is (client.name, client.withdrawalAmount)") // mã này sẽ không được biên dịch |
So where are they most commonly used?
As in other articles that mention this topic, I would say the same:
When you need a func will return many value types.
But what that means, in fact. Perhaps you will not write anything like this:
1 2 3 4 | func someClient() -> (name: String, age: Int, havePremiumAccount: Bool) { return ("John", 27, true) } |
But in at least 50% of apps, you will have something like this:
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 } |
This is great, but swift has an even better way to do this
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. |
In summary, in most cases, you will use tuple as the return type of the call API, escaping closure.
1 2 | func getClients(objectToPass: Object, completion:@escaping (SomeType, Error) → ReturnType) |
Typealias and tuples:
Tuples are great for this function, writing functions with data sets as return types is much easier if you implement them like this.
Tuples can be very long and can be repeated many times in the same method.
For example:
1 2 3 4 | typealias UserDestination = (destination:(latitude: Double, longitude: Double)) func showOnMap() -> UserDestination { } |
Practical examples:
1 2 3 4 5 6 | protocol URLSessionProtocol { typealias DataTaskResult = (Data?, URLResponse?, Error?) -> () func dataTask(request: URLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTask } |
Something else I can mention is an optional tuple:
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 |
Finally, interviewing tips can be done with tuple and you will definitely get more points We all know about fizzbuzz testing. You will get a series of numbers and you will need to check which number is divisible by the other two numbers, in most cases 3 and 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) } |
Conclusion
I hope you like this, if there is anything unclear about this, or you have something great or really advanced on this subject please comment.
Source: Medium