简体   繁体   中英

Use protocol that inherits from another protocol as an associated type

I am trying to make a protocol that has has two associated types. One of these associated types is for a delegate. When I try to use another protocol as the associated type, I get the error "Type 'HostConnectionService' does not conform to protocol 'ConnectionService'". The code I have is written below:

protocol ConnectionService: class {
    associatedtype Peer: Sharelist.Peer
    associatedtype Delegate: ConnectionServiceDelegate
    var connectedPeers: [Peer] { get }
    var delegate: Delegate? { get }
}

protocol ConnectionServiceDelegate { }

// Error
class HostConnectionService: NSObject, ConnectionService {
    typealias Peer = GuestPeer
    typealias Delegate = HostConnectionServiceDelegate

    var delegate: HostConnectionServiceDelegate?
    var connectedPeers: [GuestPeer] = []
}

protocol HostConnectionServiceDelegate: ConnectionServiceDelegate { }

When I change the line

typealias Delegate = HostConnectionServiceDelegate

to be of a non-protocol type, I no longer get an error:

struct NonProtocolConnectionServiceDelegate: ConnectionServiceDelegate { }

// No Error
class HostConnectionSertice: NSObject, ConnectionService {
    ...
    typealias Delegate = NonProtocolConnectionServiceDelegate
    ...
}

Is this a fundamental Swift limitation, or am I doing something wrong?

Your example is too complicated to understand. I tried to simplify it.

It compiles without errors:

protocol ProtocolA {}

protocol ProtocolB {
    associatedtype SomeType
}

class SomeClass: ProtocolB {
    typealias SomeType = ProtocolA
}

let object = SomeClass()

But the following example is no longer compiled:

protocol ProtocolA {}

protocol ProtocolB {
    associatedtype SomeType: ProtocolA
}

class SomeClass: ProtocolB {
    typealias SomeType = ProtocolA
}

The error is as follows:

error: type 'SomeClass' does not conform to protocol 'ProtocolB'

note: possibly intended match 'SomeType' (aka 'ProtocolA') does not conform to 'ProtocolA'

This is because protocols don't conform to themselves

Most likely in your case it is necessary to make the class template:

protocol ProtocolA {}

protocol ProtocolB {
    associatedtype SomeType: ProtocolA
}

class SomeClass<T: ProtocolA>: ProtocolB {
    typealias SomeType = T
}

extension Int: ProtocolA {}
extension Double: ProtocolA {}

let object1 = SomeClass<Int>()
let object2 = SomeClass<Double>()

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