iOS Swift: протокол и типы - PullRequest
       6

iOS Swift: протокол и типы

0 голосов
/ 06 января 2019

У меня проблемы с написанием протокола и его реализацией по умолчанию.

Протокол является RealmServiceCompatible, и объект должен соответствовать ему. В расширении RealmServiceCompatible я дал его реализацию по умолчанию, но все же, когда я согласовываю Object с ним, Xcdoe все еще просит меня скомпилировать заглушки протокола.

Я не могу понять правильный синтаксис.

protocol RealmServiceCompatible {

    associatedtype CompatibleType

    var rs: RealmService<CompatibleType> { get }
    static var rs: RealmServiceStatic<CompatibleType> { get }
}

extension RealmServiceCompatible {

    public var rs: RealmService<Self> {
        get {
            return RealmService(self)
        }
    }
    public static var rs: RealmServiceStatic<Self> {
        get {
            return RealmServiceStatic(Self.self)
        }
    }
}


extension Object: RealmServiceCompatible {

    var rs: RealmService<NSObject> {
        <#code#>
    }


    static var rs: RealmServiceStatic<NSObject> {
        <#code#>
    }

}

Xcode принял это:

protocol RealmServiceCompatible: AnyObject where CompatibleType: Object {

    associatedtype CompatibleType

    var rs: RealmService<CompatibleType> { get }
    static var rs: RealmServiceStatic<CompatibleType> { get }
}

extension RealmServiceCompatible {

    var rs: RealmService<Self> {
            return RealmService(self)
    }
    static var rs: RealmServiceStatic<Self> {
            return RealmServiceStatic(Self.self)
    }
}


extension Object: RealmServiceCompatible {
    typealias CompatibleType = Object
}

1 Ответ

0 голосов
/ 06 января 2019

Вы не предоставили реализацию по умолчанию, которая применяется:

public var rs: RealmService<Self> { ... }

Это актуально, только если CompatibleType == Self (тип класса, реализующего протокол). Но ваш протокол применяется ко всем возможным CompatibleType значениям.

Тем не менее, в прошлый раз, когда я проверял, вы не можете сделать это ни в коем случае (даже если вы позаботились о том, чтобы обработать все возможные значения CompatibleType), поскольку вы получаете циклическое определение. Реализация по умолчанию применяется только к тем вещам, которые уже соответствуют, но они не соответствуют, если у них нет реализаций. В принципе, для проверки типов можно было бы сделать шаг назад и сказать (как это делают люди): «Давайте просто притворимся, что оно соответствует, даже если это еще не так, и посмотрим, притворно ли оно соответствует на самом деле магическим образом. делает, "но я не думаю, что проверка типов делает это сегодня. (Это на самом деле довольно сложная проблема в общем случае и, вероятно, немного увеличит время компиляции, чтобы отследить все возможные способы.)

Не совсем понятно, что вы пытаетесь сделать здесь, поскольку RealmServiceCompatible, похоже, не тянет вес. Я подозреваю, что вы пытаетесь сделать что-то вроде make SomeClass().rs return RealmService<SomeClass>, в то время как SomeSubClass().rs возвращает RealmService<SomeSubClass>, но в Swift это невозможно. RealmService<SomeSubClass> не является подтипом RealmService<SomeClass>, поскольку у Swift отсутствует способ выражения ковариации, поэтому это нарушит наследование.

Такое ощущение, что вы пытаетесь создать что-то волшебное, что не сработает.

...