简体   繁体   English

Swift:将通用类型转换为协议

[英]Swift: cast generic type to protocol

Is there a way to tell the compiler that a generic type will conform with certain protocol at runtime? 有没有办法告诉编译器泛型将在运行时符合某些协议?

The compiler can't know it, but I know it, and because of that I am able to prevent users of my library from having to specify the conforming type. 编译器不知道,但是我知道,因此,我能够防止我的库用户不得不指定一致的类型。

public extension Observable {
    public func cache(provider : Provider) -> Observable<E> {
        return cacheInternal(provider) // error: Type 'Element' does not conform to protocol 'Mappable'
    }

    internal func cacheInternal<T : Mappable>(provider : Provider) -> Observable<T> {
        //implementation
    }

    //what I want to avoid
    public func cache<T : Mappable>(type: T.Type, provider : Provider) -> Observable<E> {
        //implementation
    }
}

And I can't modify the generic type 'Element (E)' to conform with Mappable protocol because Observable is a class which I'm just extending. 而且我无法修改通用类型“元素(E)”以符合Mappable协议,因为Observable是我正在扩展的类。

Thanks! 谢谢!

Conditional protocol conformance could be the solution for you. 有条件的协议一致性可能是您的解决方案。

Since your cacheInternal(provider:) function needs the conformance to the Mappable protocol, this function should only be extended for of the type Observable with a generic type E that conforms to Mappable . 由于您的cacheInternal(provider:)函数需要符合Mappable协议,因此该函数仅应使用符合Mappable的通用类型E扩展为Observable类型。 This can be achieved with a where -clause in the extension declaration: 这可以通过扩展声明where -clause来实现:

public extension Observable where E: Mappable {
    public func cache(provider : Provider) -> Observable<E> {
        return cacheInternal(provider)
    }

    internal func cacheInternal<T: Mappable>(_ provider : Provider) -> Observable<T> {
        //implementation
        return Observable<T>() //added this to silence the error that nothing is returned. Don't know, what exactly you want to return
    }
}

Footnote: I've updated the code to Swift 3 in order to test it correctly. 脚注:为了将其正确测试,我已将代码更新为Swift 3。 (can't test on 2.x at the moment) I guess it was just the _ in cacheInternal to hide the argument label. (目前无法在2.x上进行测试)我想这只是隐藏参数标签的cacheInternal_

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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