Как это сделать? Я хочу протокол, за которым могут следовать только два класса - PullRequest
0 голосов
/ 13 октября 2018

Я хочу protocol, за которым могут следовать только два класса。 (ClassA или ClassB).

protocol MyProtocol where Self: ClassA || ClassB {

}

1 Ответ

0 голосов
/ 13 октября 2018

Это требование почти наверняка указывает на проблему дизайна.Если какая-то часть вашей системы заботится о том, что реализует протокол, то протокол не захватывает весь интерфейс.Например, если в какой-то момент вы используете as? ClassA, это опасное использование протоколов.

Невозможно иметь в Swift протокол, который я вижу, но не могу реализовать.Есть такие языки, как Go, где это возможно (хотя и не совсем так, как вы описали), но сегодня это невозможно в Swift.Как отмечает @MartinR, ответ Дж. Доу на самом деле ничего не меняет.Внешние стороны все еще могут просто реализовать оба протокола.

С учетом всего вышесказанного можно достичь вещей, очень похожих на то, что вы описываете.

Во-первых, и наиболее очевидно: используйте средства управления доступом.

private protocol MyProtocol {}

public class ClassA: MyProtocol {}

public class ClassB: MyProtocol {}

Это работает, если все классы и протокол находятся в одном файле.Если нет, поместите их все в рамки и используйте internal вместо private.Теперь ничто вне этого файла / модуля не может реализовать MyProtocol.Ограничение состоит в том, что MyProtocol также нельзя увидеть вне файла / модуля.

Это можно решить, подняв структуру:

public struct MyStruct: MyProtocol {
    private let value: MyProtocol
    public init(classA: ClassA) { value = classA }
    public init(classB: ClassB) { value = classB }
    // Methods to conform to MyProtocol by forwarding to value
}

С этим невозможносгенерируйте MyStruct, который инициализируется чем угодно, кроме ClassA или ClassB.

В качестве альтернативы, если вы действительно буквально подразумеваете "ClassA или ClassB", это не структура или протокол.Это перечисление:

enum MyEnum {
    case classA(ClassA)
    case classB(ClassB)
}
...