Использовать протокол, который наследуется от другого протокола, как связанный тип - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь создать протокол, который имеет два связанных типа.Один из этих связанных типов предназначен для делегата.Когда я пытаюсь использовать другой протокол в качестве связанного типа, я получаю сообщение об ошибке «Тип« HostConnectionService »не соответствует протоколу« ConnectionService ».Код, который я написал, написан ниже:

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

Когда я изменяю строку

typealias Delegate = HostConnectionServiceDelegate

на непротокольный тип, я больше не получаю сообщение об ошибке:

struct NonProtocolConnectionServiceDelegate: ConnectionServiceDelegate { }

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

Это фундаментальное ограничение Свифта, или я что-то не так делаю?

1 Ответ

0 голосов
/ 04 марта 2019

Ваш пример слишком сложен для понимания.Я попытался упростить его.

Он компилируется без ошибок:

protocol ProtocolA {}

protocol ProtocolB {
    associatedtype SomeType
}

class SomeClass: ProtocolB {
    typealias SomeType = ProtocolA
}

let object = SomeClass()

Но следующий пример больше не компилируется:

protocol ProtocolA {}

protocol ProtocolB {
    associatedtype SomeType: ProtocolA
}

class SomeClass: ProtocolB {
    typealias SomeType = ProtocolA
}

Ошибка заключается в следующем:

ошибка: тип «SomeClass» не соответствует протоколу «ProtocolB»

примечание: возможно предполагаемое совпадение «SomeType» (он же «ProtocolA») не соответствует «ProtocolA»

Это потому, что протоколы не соответствуют друг другу

Скорее всего, в вашем случае необходимо создать шаблон класса:

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>()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...