简体   繁体   中英

iOS Swift: Protocol and Types

I'm having problems writing a protocol and doing a default implementation of it.

The protocol is RealmServiceCompatible and the Object should conform on it. In the extension RealmServiceCompatible I gave a default implementation of it, but still when I'm conforming Object to it, Xcdoe still asks me to compile protocol stubs..

I can't figure the correct syntax.

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 has accepted this:

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
}

You didn't provide a default implementation that applies:

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

This is only relevant if CompatibleType == Self (the type of the class that is implementing the protocol). But your protocol applies over all possible CompatibleType values.

That said, last time I checked, you can't do this in any case (even if you made sure to handle all possible CompatibleType values), since you get in a circular definition. The default implementation only applies to things that already conform, but they don't conform unless they have implementations. In principle, it might be possible for a type checker to take a step back and say (as humans do), "let's just pretend it does conform, even though it doesn't yet, and see if by pretending to conform it actually magically does," but I don't think the type checker does that today. (That's actually a pretty hard problem in the general case and would likely increase compile times quite a bit to chase all the ways things might work out.)

It's not really clear what you're trying to do here, since RealmServiceCompatible doesn't seem to be pulling any weight. I suspect you're trying to do something like make SomeClass().rs return RealmService<SomeClass> , while SomeSubClass().rs returns RealmService<SomeSubClass> , but that's not possible in Swift. RealmService<SomeSubClass> is not a subtype of RealmService<SomeClass> because Swift lacks a way to express covariance, so this would break inheritance.

It feels like you're trying to make something magical here that isn't going to work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM