Protocol Pitfalls

Introduction

Welcome to Lesson 4 of Generic Protocols. In Chapter 4, you’ve learned how to use protocols as a type so that you may group objects together regardless of classes, structs, and enums. With associated types, however, it no longer works. You will discover that Protocol Oriented Programming has its own flaw.

Problem

Can’t use it as a type

Design File Type

Design structs called, Folder and Cell which will be used later by the protocol.

  1. struct Folder {}
  2. struct Cell {}

Design Protocol

Design a protocol called, Listable. It contains an associated type called, FileType which will be replaced by the structs you’ve designed above.

  1. protocol Listable {
  2. associatedtype FileType
  3. func getFileType() -> String
  4. }

Design Classes

Design classes called, FolderCell, CollectionCell, ListCell.

  1. class FolderCell: Listable {
  2. typealias FileType = Folder
  3. func getFileType() -> String {
  4. return "FolderCell with \(FileType.self) type"
  5. }
  6. }

Protocol Pitfalls - 图1

  1. class CollectionCell: Listable {
  2. typealias FileType = Cell
  3. func getFileType() -> String {
  4. return "CollectionCell with \(FileType.self) type"
  5. }
  6. }
  7. class ListCell: Listable {
  8. typealias FileType = Cell
  9. func getFileType() -> String {
  10. return "ListCell with \(FileType.self) type"
  11. }
  12. }

Protocol Pitfalls - 图2

FileType of FolderCell is Folder. FileTypeof CollectionCell and ListCell is Cell.

Problem

  1. let cell: Listable = CollectionCell() // Error

Error: Listable’ can only be used as a generic constraint because it has Self or associated type requirements

You may only use Listable as a generic constraint as shown below.

  1. func enterListCell<T: Listable>(enterCell: T) {}
  2. enterListCell(enterCell: FolderCell())
  3. enterListCell(enterCell: ListCell())

The compiler does not know the type of FileType as shown below.

  1. import Foundation
  2. let cell: Listable = arc4random() * 2 == 0 ? FolderCell() : ListCell()

FileType could be Folder or Cell. It is only known when you execute the arc4Random() method. By the time it is called, it is already compiled

Source Code

6004_protocol_pitfalls

Conclusion

This is frustrating. In the following lesson, you will learn how to use the brain to circumvent the problem.

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