быстрый тип протокола - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть вопрос о типе, связанном с протоколом swift.

protocol SomeProtocol {}

protocol TestAProtocol: SomeProtocol {}

protocol TestBProtocol: SomeProtocol {}

class TestA: TestAProtocol {}

class TestB: TestBProtocol {}

protocol Service {
    associatedtype S: SomeProtocol

    var service: S? { get }
}

class ServiceModule: Service {
    var service: TestAProtocol?
}

этот код содержит ошибку, поскольку тип службы в ServiceModule - это протокол (TestAProtocol) (не конкретный тип).

class ServiceModule: Service {
    var service: TestA?
}

или

class ServiceModule: Service {
    var service: TestB?
}

все в порядке.

, но я хочу иметь переменную, соответствующую протоколу (например, TestAProtocol), которая соответствует специфицированному протоколу c (например, SomeProtocol).

вот так:

class ServiceModule: Service {
        var service: TestAProtocol? // or var service: TestBProtocol?
    }

возможно ли это?

1 Ответ

2 голосов
/ 14 апреля 2020

Это не работает, потому что вы не указали связанный тип в своем классе ServiceModule, и компилятор Swift не может вывести базовый тип. Вместо этого вы должны использовать свой протокол как общее ограничение c:

class ServiceModule<P: TestAProtocol>: Service {
    var service: P?
}

Здесь P - это конкретный тип, соответствующий TestAProtocol, который будет разрешен во время компиляции. Вызывающий объект (класс init) определит связанный тип. Здесь P будет иметь тип TestA.

let instance = ServiceModule<TestA>()

Самое важное понять, что вы не можете использовать протокол со связанным типом в качестве конкретного типа. Вы можете только:

  • Использовать его как обобщенное c ограничение
  • , использовать ключевое слово some (только для функций и вычисляемых свойств), чтобы вернуть непрозрачный тип, предлагающий реализацию.
...