Swift Generics allows us to create a single function and class (or any other types) that can be used with different data types.
This helps us to reuse our code.
Swift Generic Function
In Swift, we can create a function that can be used with any type of data. Such a function is known as a Generic Function.
Here's how we can create a generic function in Swift:
// create a generic function
func displayData<T>(data: T){
...
}
Here,
- We have created a generic function named
displayData()
. T
used inside the angle bracket<>
is called the type parameter.
And based on the type of the value passed to the function, the T
is replaced by that data type (Int
, String
, and so on).
Note: We can provide any name to the type parameter: <S>
, <Element>
, etc. But generally, we use T
.
Example: Swift Generic Function
// create a generic function
func displayData<T>(data: T) {
print("Generic Function:")
print("Data Passed:", data)
}
// generic function working with String
displayData(data: "Swift")
// generic function working with Int
displayData(data: 5)
Output
Generic Function: Data Passed: Swift Generic Function: Data Passed: 5
In the above example, we have created a generic function named displayData()
with the type parameter <T>
.
Now, when we call the generic function
displayData(data: "Swift")
we have passed a string value, so the placeholder parameter T
is automatically replaced by String
.
Similarly, when we pass Int
to the generic function
displayData(data: 5)
the placeholder is replaced by Int
.
Swift Generic Class
Similar to the generic function, we can also create a class that can be used with any type of data. Such a class is known as Generic Class.
Let's see an example,
// create a generic class
class Information<T> {
// property of T type
var data: T
init (data: T) {
self.data = data
}
// method that return T type variable
func getData() -> T {
return self.data
}
}
// initialize generic class with Int data
var intObj = Information<Int>(data: 6)
print("Generic Class returns:", intObj.getData())
// initialize generic class with String data
var strObj = Information<String>(data: "Swift")
print("Generic Class returns:", strObj.getData())
Output
Generic Class returns: 6 Generic Class returns: Swift
In the above example, we have created a generic class named Information. This class can be used to work with any type of data.
class Information<T> {...}
We have created two objects of Information
var intObj = Information<Int>(data: 6)
var strObj = Information<String>(data: "Swift")
Here,
- intObj - the type parameter
T
is replaced byInt
. Now, theInformation
works with integer data. - stringObj - the type parameter
T
is replaced byString
. Now, theInformation
works with string data.
Type Constraints in Swift Generics
In general, the type parameter can accept any data type (Int
, String
, Double
, ...).
However, if we want to use generics for some specific types (such as accepting data of number types) only, then we can use type constraints.
Here's how we create type constraints:
func addition<T: Numeric>(num1: T, num2: T) {
...
}
Here, <T: Numeric>
adds constraints to the type parameter. It defines that T
needs to conform to the Numeric
protocol.
Note: Numeric
is the built-in protocol for numeric values like Int
and Double
.
Example: Type Constraints
//create a generic function with type constraint
func addition<T: Numeric>(num1: T, num2: T) {
print("Sum:", num1 + num2)
}
// pass Int value
addition(num1: 5, num2: 10)
// pass Double value
addition(num1: 5.5, num2: 10.8)
Output
Sum: 15 Sum: 16.3
In the above example, we have created a generic function named addition()
. Notice the expression,
<T: Numeric>
Here, the generic function is created with type constraints. This means addition()
can only work with data types that conform to Numeric protocol (Int
, Double
, and so on).
Note: If we try to pass other types, say String
, we'll get an error: argument type 'String' does not conform to the expected type 'Numeric'
.
Advantages of Swift Generics
1. Code Reusability
With the help of generics in Swift, we can write code that will work with different types of data. For example,
func genericFunction<T>(data: T) {...}
Here, we have created a generics function. This same function can be used to perform operations on integer data, string data, and so on.
2. Used with Collections
Swift array uses the concept of generics. For example,
// creating a integer type array
var list1: Array<Int> = []
// creating a string type array
var list2: Array<String> = []
Here, list1 array that holds Int
values and list2 array that holds String
values.
Similar to arrays, dictionaries are also generic in Swift.