简体   繁体   中英

Swift: type does not conform to protocol

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

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

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 {}

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM