扩展通用类型,其中T具有另一种通用类型

时间:2018-05-24 03:48:08

标签: swift generics

我有一个数据模型,用于解析来自API的json。

struct APIResult<Result> {
    public let result: Result?
    ...
}

此对象接受不同的结果类型,并对其进行扩展,以便我可以在其中使用具有不同逻辑的自定义初始值设定项,以便我的APIService不会有任何样板代码。

这些是我做的扩展示例,初始化程序看起来是一样的

extension APIResult where Result: SomeClass  {
    init(_ json: Any, resultType: Result.Type) {
        ...
    }
}

extension APIResult where Result == SomeStruct  {
    init(_ json: Any, resultType: Result.Type) {
        ...
    }
}

// which then would look like this on the request function somewhere

request.warpResponse {
    completion(APIResult($0, resultType: UserProfile.self))
}

现在我遇到一个问题,当我尝试将APIResult扩展到具有自己的通用名称的对象时,例如Array<Element>,当我尝试创建扩展时,它肯定会像这样

extension APIResult where Result == Array<SomeClass>  {
    init(_ json: Any, resultType: Result.Type) {
        ...
    }
}

但是当我尝试初始化

// here's a subclass of SomeClass 
class SubClass: SomeClass { ... }

request.warpResponse {
    completion(APIResult($0, resultType: Array< SubClass >.self))
    // or
    completion(APIServiceResult($0, resultType: [SubClass].self))
}

会出现一条错误消息

  

无法转换类型'Array&lt;的值SubClass&gt; .Type'到期望的参数类型'Array&lt; SomeClass的&GT;。键入“

  

无法将'[SubClass] .Type'类型的值转换为预期的参数类型'Array&lt; SomeClass&gt; .Type'

有没有办法以某种方式解决这个问题?

1 个答案:

答案 0 :(得分:1)

您可以使用协议代替Array<SomeClass>,并在ArrayElement类型的情况下使SomeClass符合该协议。

这样的事情:

struct APIResult<Result> {
    public let result: Result?
}

protocol SomeProtocol { }

class SomeClass { }

class SubClass: SomeClass {   }

extension APIResult where Result: SomeProtocol  {
    init(_ json: Any, resultType: Result.Type) {
        result = nil
    }
}

extension Array: SomeProtocol where Element: SomeClass {

}

APIResult("", resultType: Array<SubClass>.self)