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