Ограничить связанный тип для универсального класса - PullRequest
0 голосов
/ 02 апреля 2019

Я пытаюсь создать протокол со связанным типом, который имеет инициализатор, который принимает класс, соответствующий протоколу, в качестве типа аргумента. Это само по себе прекрасно работает:

protocol A {
    associatedtype B: C where C.InitializableBy == Self
}

protocol C {
    associatedtype InitializableBy
    init(arg: InitializableBy)
}

Однако, поскольку я не хочу писать новый инициализатор для каждого класса, я хочу, чтобы ограничение типа B было классом. Я попробовал этот подход:

protocol A {
    associatedtype B: D<Self>
}

class D<T> {
    init(arg: T) { ... }
}

но это не работает, или, по крайней мере, я не смог заставить класс соответствовать протоколу таким образом. Единственный способ заставить его работать, это использовать класс и протокол:

protocol A {
    associatedtype B: C where C.InitializableBy == Self
}

protocol C {
    associatedtype InitializableBy
    init(arg: InitializableBy)
}

class D<T> : C {
    typealias InitializableBy = T
    init(arg: T) { ... }
}

Таким образом, класс может соответствовать A, имея вложенный тип, который реализует D и не должен переопределять инициализатор:

class Test: A {
    class B: D<Test> {}
}

Но я бы хотел обойти использование "фиктивного протокола" C, поскольку он не предназначен для реализации другими классами, кроме D.

1 Ответ

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

Это все, что вам нужно.

protocol A {
    associatedtype B = D<Self>
}

class D<T> {
    init(arg: T) {}
}

или

protocol A {
    typealias B = D<Self>
}

class D<T> {
    init(arg: T) {}
}

Причина, по которой ваш код не работает так, заключается в том, что : означает "соответствует", а не'является'.Вы просто хотите дать другое имя D, если я не ошибаюсь.

...