Type Eraser

Introduction

Welcome to the last lesson of Generic Protocols. In the previous lesson, you’ve discovered the problem that occurs when you work with protocol as a type. Let us find an alternative.

Problem

Let’s circumvent the problem

Design Protocol, Struct, Classes

The example from the previous lesson is used.

  1. // Design FileType
  2. struct Folder {}
  3. struct Cell {}
  4. // Design Protocol
  5. protocol Listable {
  6. associatedtype FileType
  7. func getFileType() -> String
  8. }
  9. // Design Classes
  10. class FolderCell: Listable {
  11. typealias FileType = Folder
  12. func getFileType() -> String {
  13. return "FolderCell with \(FileType.self) type"
  14. }
  15. }
  16. class CollectionCell: Listable {
  17. typealias FileType = Cell
  18. func getFileType() -> String {
  19. return "CollectionCell with \(FileType.self) type"
  20. }
  21. }
  22. class ListCell: Listable {
  23. typealias FileType = Cell
  24. func getFileType() -> String {
  25. return "ListCell with \(FileType.self) type"
  26. }
  27. }

Important: Make sure you review generics and closures to fully understand what’s coming.

Design Wrapper

Design a generic class called, AnyCell. It conforms to the Listable protocol. It has an init method which you must enter an object that conforms to Listable.

  1. class AnyCell<T>: Listable {
  2. typealias FileType = T
  3. private let _getFileType: () -> String
  4. init<U: Listable>(_ enterAnyCell: U) where U.FileType == T {
  5. // T defined based on U
  6. _getFileType = enterAnyCell.getFileType
  7. }
  8. func getFileType() -> String {
  9. return _getFileType()
  10. }
  11. }

Execute

Use AnyCell to create an object.

  1. let collectionCell: AnyCell = AnyCell(CollectionCell())
  2. let listCell: AnyCell = AnyCell(ListCell())

You may group items whose FileType is identical.

  1. let fileTypeWithCells = [collectionCell, listCell]
  2. print(fileTypeWithCells[0].getFileType())
  3. print(fileTypeWithCells[1].getFileType())

Type Erasing: Erase Abstract Type (associatetype, T) to Concrete Type (String, Int, File, Cell)

Source Code

6005_type_erasing.playground

References

Protocol Oriented Programming is Not a Silver Bullet by Chris Eidhof

Beyond Crusty: Real-World Protocols by Rob Napier

Conclusion

The lesson could have been tough since it assumes you’ve mastered generics and closures. If you are stuck, I recommend you to get the fundamentals of them and then come back after. If you wish to study more, I recommend you to take a look at the references I’ve attached. They focus on why Protocol Oriented Programming is not the ultimate savior for all cases. Often, it is recommended you use pure structs or enums which you will learn in-detail in the following chapter. Anyhow, the person who came up with the solution is definitely smarter than I’m.

Note: Learn Swift with Bob is available on Udemy. If you wish to receive a discount link, you may sign up here.