Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protocol associatedType and <>

what is a difference between using generic with function or using associatedType in swift protocols?

protocol Repository {
    associatedtype T
    func add(data : T) -> Bool
}

and

protocol Repository {
    func add<T>(data : T) -> Bool
}
like image 443
Muhammad Aamir Ali Avatar asked Oct 29 '18 08:10

Muhammad Aamir Ali


Video Answer


3 Answers

Defined associated type makes classes which conform protocol strong typed. This provide compile-time error handling.

In other hand, generic type makes classes which conform protocol more flexible.

For example:

protocol AssociatedRepository {
    associatedtype T
    func add(data : T) -> Bool
}

protocol GenericRepository {
    func add<T>(data : T) -> Bool
}


class A: GenericRepository {
    func add<T>(data : T) -> Bool {
        return true
    }
}

class B: AssociatedRepository {
    typealias T = UIViewController
    func add(data : T) -> Bool {
        return true
    }
}

class A could put any class into add(data:) function, so you need to makes your sure that function handle all cases.

A().add(data: UIView())
A().add(data: UIViewController())

both would be valid

But for class B you will get compile-time error when you will try to put anything except UIViewController

B().add(data: UIView()) // compile-time error here
B().add(data: UIViewController())
like image 50
Taras Chernyshenko Avatar answered Oct 19 '22 05:10

Taras Chernyshenko


  • An associatedtype is a static type in struct/class which adopts the protocol either via a typealias declaration or via type inference. The type is always the same for that class.

  • A generic can be anything, even different types in the same class.

like image 31
vadian Avatar answered Oct 19 '22 06:10

vadian


This case

protocol Repository {
    func add<T>(data : T) -> Bool
}

Is understood by compiler like: "Any type that is fed to the func add will be acceptable and the result of the function will be Bool"

But this

protocol Repository {
    associatedtype T
    func add(data : T) -> Bool
}

is understood by compiler like: "func add will accept only the type that is defined in the typealias T = ... and return Bool"

In the second case you restrict generic parameters only to the typealiased types.

Another important feature shows up when you use generic parameters in multiple functions of the protocol. In that case it guarantees that func add<T> and func multiply<T> will have the same type T. In case of generic functions it is not guaranteed.

protocol Calculable {
    associatedtype T
    func add<T>(a: T, b: T) -> T
    func multiply<T>(a: T, b: T) -> T
}
// In this case you know that T is the same for all functions

protocol CalculableDifferent {
    func add<T>(a: T, b: T) -> T
    func multiply<T>(a: T, b: T) -> T
}
// In this case add can accept One type, when multiply can accept Another
like image 3
fewlinesofcode Avatar answered Oct 19 '22 05:10

fewlinesofcode