Get up to 80 % extra points for free! More info:

Lesson 1 - Introduction to collections and genericity in Swift

In today's lesson of our Swift course, we'll introduce collections and genericity and go over a bit of background information about it. Then, we'll discuss different build-in collections in more detail in the following lessons.

Collections

The term "collection" refers to a set of items which are mostly of the same data type, and are used for a specific purpose. Throughout the previous Swift courses, we've already encountered arrays (Array), the basic collection. Swift makes choosing between collections easy, because it provides just three of them. We already know arrays. Later, we'll get familiar with more advanced methods and have a look at the remaining Dictionary and Set collections.

Generic and non-generic collections

If we thought about making our own collection, we'd run into issues very soon. One of which would be choosing the data type for the collection items. For example, if we wanted to program our own Array, we would create a MyArray.swift class and add the appropriate methods to it. Since we want to make our collection universal and to be able to store any sort of items, e.g. both Ints or users, we would run into issues with the data types of the elements within the collection. There are two ways to solve this problem but only one of them is used in practice. The better one, of course :-)

Non-generic collections

In Swift, we can assign any data type to the Any type. We could set this type to a non-generic collection to be able to put anything in it. The downside to this approach is that the collection won't know the actual type for each of the items. Therefore, it would only be able to return these elements simply as general objects. Meaning that we would have to cast anything returned by the collection.

Generic collections

Generic collections solve the data-type problem on the Swift language level. They introduce genericity. Simply speaking, it's the ability to specify the data type at the moment when an instance is created. In the collection class, we work with a generic type which serves as a placeholder for future data types. You may see it as a class that changes into others when an instance is created, for example, a String. It's sort of a class parametrization.

We already know the generic Array and that the data type (parameter) of generic classes uses angle brackets. We only have the ability to specify the data type once, when we're creating the collection. This way, we no longer need to cast items. Although we used a simpler syntax to create arrays, it's possible to do it like this as well:

var array = Array<String>()
array.append("item")

let item = array[0]

The [String]() notation we've used until now would work the same.

Genericity

Genericity is, of course, a feature of the Swift language, so we have the privilege to use it in our classes.

At this point, we won't bother with creating our own collection. Instead, let's create a simple class that will manage a single variable. The variable will be generic, so we'll be able to store any data type in it. Create a new console application project and name it Genericity. Add a new class and name it MyClass. Let's add the generic parameter in its declaration and name it T:

class MyClass<T> {

}

We are able to enter multiple generic parameters into the angle brackets, separated by commas. This may be useful at times, we'll go further into things like this once we get to generic dictionaries.

Let's move to the main.swift file and create an instance of our class:

let instance = MyClass<Int>()

Don't forget to provide the angle brackets in both the data type and the constructor. We've specified the Int data type in the T parameter for this class instance. We could also make another instance of the same class and give it a totally different data type, e.g. String. For our intents and purposes, a single class is enough for storing multiple data types.

Let's continue and create a class property. We are able to use T as an ordinary data type:

private var variable: T
init(variable: T) {
    self.variable = variable
}

Make sure to update the instance creation in the main.swift:

let instance = MyClass<Int>(variable: 10)

The instance contains the "variable" property now, which is of the Int type and contains a value of 10.

We could even add a method with an extra generic parameter (other than the one that the class currently has). It could look like this:

func compare<T2>(a: T2) -> Bool {
    return type(of: variable) == type(of: a)
}

The method compares the data type of the variable property with the data type of the parameter. It could do anything else with the parameters though. Let's compare our Int with another data type:

instance.compare(a: "text")

Other constructions

For completeness' sake, we'll introduce you to a few more constructs.

A generic class parameter can be specified in more detail, furthermore, it can be limited using the colon after the generic parameter. Like that, we can ensure, for example, that the data type has to implement the Equatable protocol (to make the == operator work):

class MyClass<T: Equatable> {
    // ...
}

This allows us to call the interface's methods on the variables of the T type from within the class. The interface itself can also contain a generic parameter, so we could use generic types in its methods' headers.

Or we can use the where keyword notation:

class MyClass<T> where T:Equatable {
    // ...
}

It depends on your taste. I would recommend using where if your class has multiple specifications.

If we want to specify multiple protocols, we separate them using & in the first approach; when using where, we just separate them by commas and repeat the parameter we're writing the specification for.

class MyClass<T> where T: Equatable, T: Comparable {
    // ...
}

In the next lesson, Filtering and mapping arrays in Swift, we'll look at arrays again and introduce more advanced methods. You'll learn to sort a array and filter it using custom parameters.


 

All articles in this section
Collections in Swift
Skip article
(not recommended)
Filtering and mapping arrays in Swift
Article has been written for you by Filip Němeček
Avatar
User rating:
No one has rated this quite yet, be the first one!
Activities