Reputation: 135
protocol A {}
protocol B {
var a: A { get }
}
struct StructA: A {}
struct StructB {
var a: StructA
}
extension StructB: B {}
This produces the error :
Type 'StructB' does not conform to protocol 'B'
The StructA
already conform to protocol A
, and StructB
's property a
return StructA
type. That seems pretty a protocol B conformed type.
But why?
Xcode version 7.3 which Swift version is 2.2
Upvotes: 4
Views: 2048
Reputation: 369
I am reworking this code from swift 3.0.
extension WallPost: PFSubclassing {
static func parseClassName() -> String { return "WallPost" } }
This generates the error: Type 'WallPost' does not conform to protocol 'PFSubclassing'
Unavailable class method 'object()' was used to satisfy a requirement of protocol 'PFSubclassing'
Any idea of why this is happening and how I can resolve it? I wanted to fix this before updating to swift 4.0 / 5.0
Thanks so much for the help!
Upvotes: 0
Reputation: 80781
To better illustrate the problem with your current code, let's say you have a StructC : A
.
Your protocol B
says that you can assign StructC
to a
(as it conforms to A
) – but StructB
says you cannot assign StructC
to a StructA
type. Therefore StructB
doesn't conform to B
.
The solution is either to change the type of a
from StructA
to A
as Rahul says, or better yet, you could use generics.
The advantage of using generics is once you create your StructB
with a given a
– that property's type will be inferred by Swift, giving you better type safety. For example, once you assign a StructA
to it, its type will then be StructA
. If you assign a StructC
to it, its type will be StructC
.
To do this, we just have to add an associatedtype
to protocol B
. This will define a 'placeholder' type that we can then implement in a type that conforms to B
. We can then define the generic type T
in StructB
that will provide the 'implementation' of AType
– making sure it conforms to A
. Therefore, we are now free to assign either StructA
or StructC
to a
, without losing type safety.
protocol A {}
protocol B {
// new associated type to hold the type of "a" which conforms to A
associatedtype AType:A
var a: AType { get }
}
struct StructA: A {}
struct StructC:A {}
// define the new generic T which conforms to A
struct StructB<T:A> {
// define the type of a as the generic T, which conforms to A (and thus conforms with the protocol)
var a : T
}
extension StructB: B {}
let s = StructB(a: StructA())
s.a // "a" is now of type StructA
let s1 = StructB(a: StructC())
s1.a // "a" is now of type StructC
Upvotes: 3
Reputation: 3628
Because Swift is statically typed and does not depend on dynamic dispatch. You could do something like below.
import UIKit
protocol A {}
protocol B {
var a: A { get }
}
struct StructA: A {}
struct StructB {
var a: A = StructA()
}
extension StructB: B {}
Upvotes: 2