代码之家  ›  专栏  ›  技术社区  ›  Zonily Jame

扩展一个泛型类型,其中t具有另一个泛型类型

  •  0
  • Zonily Jame  · 技术社区  · 6 年前

    我有一个数据模型,用来解析来自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<subclass>.type”类型的值转换为所需的参数类型“array<someclass>.type”

    无法将类型'[Subclass].Type'的值转换为所需的参数类型'Array<SomeClass>。类型'

    有办法解决这个问题吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Mukesh    6 年前

    您可以使用协议代替 Array<SomeClass> 并使 Array 如果符合该协议 Element 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)