Generic functions are not constrained to predefined types. In this video,explore how to implement a generic function and how it can be used with a variety of types.
- [Instructor] Implementing a new function for every type leads to a lot of redundant code. To avoid code duplication we can combine all the different functions into a single generic function. Let's see how. I open up our project in the exercise files, chapter three, 0302, start. To create a generic function, we need to provide at least one placeholder type. The placeholder must appear right after the function name between angle brackets.
Note that we could've used any other identifier. Capital T is just a popular way to defer to generic placeholders. From now on we can refer to this placeholder type in the argument list or anywhere in the function's body. So, let's add the argument list. It has a left hand side argument and I'm going to use a placeholder type and same for the right hand side argument. The function returns as usual, a Bool value.
Let's implement it. I'm going to return the result of comparing the two arguments. As you can see, we get an error. Binary operator equals can not be applied to two T operants. The comparer doesn't know how to compare the two placeholder types. In Swift a type must conform to the equatable protocol to test whether it's instances are equal. So, we can only use types that adopt the equatable protocol with our equals function.
This requirement can be enforced by applying a type constraint on the placeholder type. A type constraint specifies that the type must conform to a particular protocol or inherit from a specific class. So, let's apply the type constraint. The syntax is simple, we place a constraint after the placeholder separated by a colon. Now, the function can only accept instances of types that adopt the equatable protocol. The generic version will accept any type that implements the equatable protocol.
We could compare two string instances for example. Let's compare a string abcd with the string dcba. It should evaluate for us. So, let's compare two doubles. Double.pie and 3.14. This should evaluate also to false because of the different precision that is used in this constant and the value we provided as a right hand argument.
Or it could even compare data instances. I'm going to create two constants let's call it d1. And I'm going to use the data initializer which creates data out of a series of bytes. Or we can even compare data types. I'm going to create two constants of type data. Let's call it d1 and I initialize it using the init repeating count instance method.
This creates a data object using a repeating byte pattern. Let's initialize it with once then once. And I create another constant d2, which has the same content. Now, they should evaluate to equal, 'cause their content is the same. Our genetic function will work with most basic types from the Swift standout library. As they conform to the equatable protocol.
Generic functions prevent cluttering our code with many similar functions. By avoiding code duplication, our code can stay clean and becomes less prone to bugs and errors.
- Comparing object-oriented programming with protocol-oriented programming
- Methods and class-bound protocols
- Adopting a protocol
- Declaring asynchronous behavior
- Preparing and implementing fallback logic
- Implementing an app using protocol-oriented programming