Быстрые протоколы и повторения типов - возможно ли это? - PullRequest
0 голосов
/ 24 апреля 2019

Я пытаюсь построить протоколы ProtocolA, ProtocolB и ProtocolC и классы на их основе, где:

public protocol ProtocolA {
    associatedtype B: ProtocolB
    associatedtype C: ProtocolC
    var arrayB: [B] {get set}
    var someNumber: C {get set}
}

public protocol ProtocolB {
    associatedtype A: ProtocolA
    associatedtype C = A.C
    var arrayC: [C] {get set}
    var parent: A? {get set}
}

public protocol ProtocolC {
    init()
}

Выглядит хорошо, я могу определить классы:

open class ClassA<BC:ProtocolB, CC:ProtocolC>: ProtocolA {
    public typealias B = BC
    public typealias C = CC
    public var someNumber: CC = CC()
    public var arrayB: [BC] = []
}

open class ClassB<AC:ProtocolA> : ProtocolB{
    open var arrayC: [AC.C] = []
    public typealias A = AC
    public typealias C = AC.C // 
    public var parent: AC? = nil
}

open class ClassC: ProtocolC {
    required public init()  {
    }
}

Но сейчас нет способа инициировать ClassA или ClassB:

let c = ClassC() // OK
let b = ClassB<ClassA<ClassB<ClassA.....>>>, ClassC>() // No way
let a = ClassA<ClassB<ClassA<ClassB...>>>, ClassC>() // No way either

Есть ли способ обойти эту и подобные проблемы?

1 Ответ

0 голосов
/ 25 апреля 2019

Я удалил некоторые части (например, ProtocolC), не относящиеся к этой проблеме циклического объявления, для краткости, и вот мы:

protocol ProtocolA {
    associatedtype B: ProtocolB
    var arrayB: [B] {get set}
}

protocol ProtocolB {
    associatedtype A: ProtocolA
    var parent: A? {get set}
}

protocol TypeProviderProtocol {
    associatedtype A: ProtocolA
    associatedtype B: ProtocolB
}

struct TypeProvider: TypeProviderProtocol {
    typealias A = ClassA<TypeProvider>
    typealias B = ClassB<TypeProvider>
}

class ClassA<T: TypeProviderProtocol>: ProtocolA {
    typealias B = T.B
    var arrayB: [B] = []

    func actionA() {
        print("in ClassA")
    }
}

class ClassB<T: TypeProviderProtocol> : ProtocolB{
    typealias A = T.A
    var parent: A? = nil

    func actionB() {
        print("in ClassB")
    }
}

let a = ClassA<TypeProvider>()
let b = ClassB<TypeProvider>()

a.arrayB = [b]
b.parent = a

for child in a.arrayB {
    // we know exact type of ClassA children so we can call it here
    child.actionB()
}

// and the same for ClassB parent type
b.parent?.actionA()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...