Closures
Closures are self contained lines of code that can be passed around the application and similar to blocks in Objective-C. A typical closure syntax in Swift looks as shown below
Closure Syntax
[code language=”swift”]{ (parameters) -> return type in
statements
}[/code]
Example closure in Swift
[code language=”swift”]{ (name:String, message:String -> (String) in
message + ” ” + name + ” !!!”
}
greetings(“Ravi”,”Welcome”)
[/code]
In the above code example, a closure has been assigned to a variable. The purpose of this closure is to concatenate the string parameters and return the appended message as return parameter.
Type Inference
The example closure can modified to ignore to the parameter types and closure supports type inference.
[code language=”swift”]var greetings = { (name, message) -> (String) in
return message + ” ” + name + ” !!!”
}
greetings(“Ravi”,”Welcome”)[/code]
Implicit return
In single expression closure, you can omit the return keyword.
[code language=”swift”]var numbers = [23,45,67,89,89,78]
numbers.sort { (number1, number2) -> Bool in
return number1 < number2
}
// numbers.sort { number1, number2 in return number1 < number2 }
numbers.sort { number1, number2 in number1 < number2 } // Shorthand argument syntax
numbers.sort { $0 < swift }[/code]
Shorthand Argument Syntax
Swift supports shorthand argument names for inline closures. In the above example used for implicit returns, the two parameters can be removed and represented in shorthand arguments as shown below.
[code language=”swift”]numbers.sort { $0 < swift }
[/code]
Trailing Closure
In a function with closure as the last parameter, the closure can be treated as trailing closures i.e closures outside the function parenthesis call. This is quite helpful in reducing the long closure expression. For example, the sorted function has closure as the last parameter and with trailing closure this becomes as shown below.
[code language=”swift”]var numbers = [23,45,67,89,89,78]
var sortedNumbers = sorted(numbers, {$0 > swift}) // Without trailing closure
// var sortedNumbers = sorted(numbers) {$0 > swift} // represented as trailing closure
sortedNumbers[/code]
Extensions
Swift extensions are similar to category in Objective-C which adds new functionally to existing class, enumeration or Struct. Extension does not require the source code of original class or enumeration type or struct to extend their functionality.
Listed below is an example which extends String class. A new function fromDouble has been added to String class which takes a double value and returns String.
[code language=”swift”] extension String {
static func fromDouble(doubleValue: Double) -> String {
var temp = String(format: “%.2f”, doubleValue)
return temp as String
}
}
String.fromDouble(24.50)[/code]
Generics
Generics are code that produces the same result irrespective of the data type. Listed below is a function that accepts an array of type string and reverses the array items.
[code language=”swift”]let strTemp = [“Deepak”,”John”,”Steve”,”Ravi”,”Ganesh”]
// reverse array with String
func reverseString(items: Array) -> Array {
var temp = Array()
return items.reverse()
}
reverseString(strTemp)[/code]
Now the below function accepts array of number and reverses the items
[code language=”swift”] let numbers = [23,45,56,78,98]
// reverse array with numbers
func reverseNumber(items: Array) -> Array {
return items.reverse()
}
reverseNumber(numbers)[/code]
Generics solves the problem of having different set of code for different data types by implemting the functionality for a generic type.
[code language=”swift”]let strTemp = [“Deepak”,”John”,”Steve”,”Ravi”,”Ganesh”]
let numbers = [23,45,56,78,98]
func reverseItems(items:[T])-> [T] {
return items.reverse()
}
reverseItems(strTemp)
reverseItems(numbers)[/code]
You can also implement a Generic class with this function as shown below.
[code language=”swift”]let strTemp = [“Deepak”,”John”,”Steve”,”Ravi”,”Ganesh”]
class ReverseDemo {
func reverseItems(items:[P])-> [P] {
return items.reverse()
}
}
let reverseDemo = ReverseDemo()
reverseDemo.reverseItems(strTemp)
[/code]
Swift Operations with Generics
Let us say you want to create a generic function that returns the square value of the given number. The immediate solution that comes to your mind is
[code language=”swift”]func squareOfNumber(number:M -> M{
return number * number
}
[/code]
This is not as straight forward as we think, you would notice an error – “Binary operator ‘*’ cannot be applied to two M operands”. The generic data type does not recogonize the operator ‘*’. We can fix this by creating a new protocol that tells about this operator ‘*’ and Generic type should conform to this protocol as shown below.
[code language=”swift”]protocol Multipliable {
func *(lhs:Self, rhs: Self) -> Self
}
func squareOfNumber(number:M -> M{
return number * number
}
[/code]
Then add an extension to Int, Float and other required types and make them conform to Multipliable protocol.
[code language=”swift”]extension Int: Multipliable {}
extension Float: Multipliable {}
squareOfNumber(20)[/code]
Download source code from gitHub (Generic)