Home > Blockchain >  Difference between protocol combining typealias and empty conforming protocol
Difference between protocol combining typealias and empty conforming protocol

Time:10-28

Is there a difference between these two in Swift?

  • protocol ABProtocol: AProtocol, BProtocol {}
  • typealias ABProtocol = AProtocol&BProtocol

CodePudding user response:

To make things clearer, I will rename the second one to:

typealias ABProtocolIntersection = AProtocol & BProtocol

I can think of two differences off the top of my head.

If your type conform to AProtocol and BProtocol, the type is automatically a subtype of ABProtocolIntersection, but it does not automatically conform to ABProtocol. After all, ABProtocol is a totally different protocol.

Example:

class Foo: AProtocol, BProtocol { ... }

func foo<T: ABProtocolIntersection>(type: T.Type) {  }
func bar<T: ABProtocol>(type: T.Type) { }

foo(type: Foo.self) // works
bar(type: Foo.self) // error

Another difference is that you can put extensions on ABProtocol, but not ABProtocolIntersection:

extension ABProtocol { } // OK

extension ABProtocolExtension { } // error

This is because ABProtocolIntersection is a non-nominal type, similar to types like (Int, Int) or (Int) -> String. See also: What is a 'non-nominal type' in Swift?

CodePudding user response:

Yes there is a difference. The former defines a new protocol to which types must conform when it is used. The latter only defines a "placeholder" for AProtocol&BProtocol

Consider the following code:

protocol AProtocol{}
protocol BProtocol{}

protocol ABProtocol1: AProtocol, BProtocol {}
typealias ABProtocol2 = AProtocol & BProtocol

func f1(value: ABProtocol1) {}
func f2(value: ABProtocol2) {}

Arguments to f1 must conform to ABProtocol1 but arguments to f2 can conform to AProtocol and BProtocol. You do not need to explicitly conform types to ABProtocol2. For example:

struct A: AProtocol, BProtocol
{
}

f1(value: A()) // Error!
f2(value: A()) // OK
  • Related