Tuple is our new friend in Swift. Just try to use it more, and your life would become easier, trust me!
A quick and simple example, when encountering a swap method, we always do like this:
func swapMe<T>(inout a: T, inout b: T) {
let temp = a
a = b
b = temp
}
But if we turn to tuple, there is even no need to take additional space, and the code becomes very clear:
func swapMe<T>(inout a: T, inout b: T) {
(a,b) = (b,a)
}
In the Cocoa APIs written in Objective-C, there are some methods that accepts a pointer as an argument, and fill output data back to that pointer. Mostly, it is due to a limitation of single return value in Objective-C. Take an example, CGRectDivide
is a help method on CGRect
, which is used to split a rectangle into two parts with a specified position and orientation:
/*
CGRectDivide(CGRect rect, CGRect *slice, CGRect *remainder,
CGFloat amount, CGRectEdge edge)
*/
CGRect rect = CGRectMake(0, 0, 100, 100);
CGRect small;
CGRect large;
CGRectDivide(rect, &small, &large, 20, CGRectMinXEdge);
The code above will split the rect
({0, 0, 100, 100}) into a small
one ({0, 0, 20, 100}) and a big
({20, 0, 80, 100}). Both of them is assigned by passing a pointer into the method, which could not be understood by intuition.
However, in Swift, this method is rewritten and now it returns a tuple which contains both parts:
extension CGRect {
//...
func divide(atDistance: CGFloat, fromEdge: CGRectEdge)
-> (slice: CGRect, remainder: CGRect)
//...
}
When we use this method, it is very clean and just do what it should now:
let rect = CGRectMake(0, 0, 100, 100)
let (small, large) = rect.divide(20, fromEdge: .MinXEdge)