Is there a difference between B & C below or are they equivalent?
protocol A {}
protocol B where Self : A {}
protocol C: A {}
Is there a difference between B & C below or are they equivalent?
protocol A {}
protocol B where Self : A {}
protocol C: A {}
Intuitively, I would say they are not the same:
C
inherits A
(protocol inheritance)B
does not inherit A
, but puts a constraint on which types can adopt it.B
does seem to inherit A
, as the following code demonstrates.
protocol A {}
protocol B where Self : A {}
protocol C: A {}
struct Foo: B {
}
func fubar (_ p: A) {
print (type (of: p))
}
let u = Foo ()
let p: A = u
fubar (u) // prints Foo
fubar (p) // prints Foo
It appears that protocol conformance only requires a protocol's requirements to be satisfied, not that a type explicitly adopts it (by placing the protocol’s name after the type’s name).
Actually, the docs say so: " Any type that satisfies the requirements of a protocol is said to conform to that protocol." So conforming to a protocol and adopting a protocol are not the same.
protocol A {
func a()
}
protocol B where Self : A {
func b()
}
struct Foo: B { // gives: Type 'Foo' does not conform to protocol 'A' if func a() is not present
func b() { }
func a() { }
}
Adding a bit to my first answer: I think as types B
and C
are not the same, a C
is-an A
, wheres a B
is-not-an A
, that would be my thinking here.
Thank you for clarifying the subtlety.
How exactly could you check this? C is A
is a compilation error
They are equivalent. Each of the following pairs are equivalent:
protocol P: Q {}
protocol P where Self: Q {}
func f<T: P>(_: T) {}
func f<T>(_: T) where T: P {}
associatedtype A: P
associatedtype A where Self.A: P
The desugaring is documented in Chapter 4 of swift/docs/Generics at main · swiftlang/swift · GitHub. To build it, install MacTeX and run make
in docs/Generics.
You can check that a type parameter constrained to C satisfies a conformance requirement to A or whatever:
func f<T: C>(_ t: T) { g(t) }
func g<T: A>(_: T) {}