Generics in iOS swift

Abhimuralidharan
3 min readMay 18, 2017

--

Apple doc says: Generic code enables you to write flexible, reusable functions and types that can work with any type. You can write code that avoids duplication by using generics in most cases.

Generics are one of the most powerful features of Swift, and much of the Swift standard library is built with generic code. In fact, you’ve been using generics throughout the Language Guide, even if you didn’t realize it. For example, Swift’s Array and Dictionary types are both generic collections. You can create an array that holds Int values, or an array that holds String values, or indeed an array for any other type that can be created in Swift. Similarly, you can create a dictionary to store values of any specified type, and there are no limitations on what that type can be.

Lets understand generics with the help of good code and bad code.

Example:

Consider two arrays:

let intArray = [1,2,3,4,5] // type intlet stringArray = [“abhi”, “iOS”] // type string

We need to print all values in these two arrays. Let’s create a function to print int array, and another function to print all string values in string array.

func printIntArray(arr:[Int]) {arr.map { print($0) } // loop through the array and print all values}
func printStringArray(arr:[String]) {
arr.map { print($0) } // loop through the array and print all values}printIntArray(arr: intArray) // prints all values in intArrayprintStringArray(arr: stringArray) //prints values in stringArray

This code looks verbose. It can be further simplified using generic function.

func printAnyArray<T>(arr:[T]) {arr.map { print($0) }}printAnyArray(arr: intArray)printStringArray(arr: stringArray)

Here , instead of two methods to print int and string as in the previous code sample,we created one generic method which can print array with any type values.

Notice the letter T I put between < and >. I pick to put T there. You can put whatever. But the parameter type should be the same . So the <T> after the function name represents a generic function. A generic function can work with whatever type.

The T that we used here is a placeholder type. In most cases T doesn’t really say much. Hence we would want to have a more descriptive name like Key and Value in Dictionary<Key, Value>and Element in Array<Element>.

Generic function with multiple parameters:

The syntax is the same as before. Just add one more placeholder type along with the placeholder type T between the < and > i f you want to pass one more parameter of different kind to the generic function. Check the example below. you will understand better.

//Declare
func anotherMethod<T, U> (first: T, second: U) { print("first one called")}
func anotherMethod<T> (first: T, second: T) { print("second one called")}//Call
anotherMethod(first: 123, second: "456") // T - Int, U - String
anotherMethod(first: 123, second: 456) // T - Int

If they are of the same type, the second implementation is called. Otherwise the first method will get called.

Generic function with type constraints:

Consider the following example:

func middleVal<T>(array: [T]) -> T? {
guard !array.isEmpty else { return nil }
return array.sorted()[(array.count - 1) / 2]
}

It accepts an array of type T and sort the array to find the middle value. But this method will throw an error at this point. Because, for the sort() method to work, the array elements should confirm to Comparable protocol. So we should add a type constraint to the type T as follows:

func middleVal<T: Comparable>(array: [T]) -> T? {
guard !array.isEmpty else { return nil }
return array.sorted()[(array.count - 1) / 2]
}

Enjoy!!

If you enjoyed reading this post, please share and recommend it so others can find it 💚💚💚💚💚💚 !!!!

--

--