【问题标题】:Swift nested generics type does not conform to protocolSwift 嵌套泛型类型不符合协议
【发布时间】:2016-04-21 03:56:54
【问题描述】:

我有一个 Response 类包含一个值,我还有一个 Value 类包含符合 Mappable 协议的数据。

现在我有一个函数来处理响应对象,但是当我尝试从值对象中获取数据时,它显示类型“R”不符合协议。

这是我在操场上的代码:

更新

protocol Mappable{
    func doSomething()
}

class User: Mappable {
    func doSomething() {

    }
}

class Book: Mappable {
    func doSomething() {

    }
}

class Value<T: Mappable>: Mappable{
    var data: T?

    func doSomething() {

    }
}

class Response<T>{
    var value: T?
}

func handleResponse< R: Mappable, T:Value<R>>(response:Response<T>, completeHandler: (R?, NSError?)->()){
    completeHandler(response.value!.data, nil)  //error goes here: Type "R" does not conform to protocol Mappable

}


let response = Response<Value<User>>()
response.value = Value<User>()
response.value?.data = User()

let response2 = Response<Value<Book>>()
response2.value = Value<Book>()
response2.value?.data = Book()

handleResponse(response, completeHandler:{(r,e)in
    print(r)
})

handleResponse(response2, completeHandler:{(r,e)in
    print(r)
})

我做得对吗?或任何其他方式来实现这一点。 谢谢

【问题讨论】:

    标签: swift generics nested-generics


    【解决方案1】:

    我不太确定为什么您的代码不起作用。我认为这是因为 Swift 难以在泛型中推断泛型的类型。

    我设法通过包装response 类型本身来编译它,而不是为Value&lt;R&gt; 定义一个新的泛型。例如:

    func handleResponse<R: Mappable>(response:Response<Value<R>>, completeHandler: (R?, NSError?)->()){
        completeHandler(response.value!.data, nil)
    }
    

    我很想知道是否有人确切知道为什么您的原始代码不起作用!

    【讨论】:

    • 是的,这样定义函数就可以了。谢谢。
    • 我怀疑在编译时,它实际上并不知道我的泛型 R 符合协议,所以当我访问泛型 T 中的数据时,它假定我的 R 只是一个 AnyObject。
    【解决方案2】:

    嘿,在 handleResponse() 函数中访问 response.value 实际上会使编译器崩溃,这肯定是编译器中的一个错误。我重写了你的代码,所以它编译:

    import Foundation
    
    protocol Mappable {
        func doSomething()
    }
    
    class User: Mappable {
        func doSomething() {
    
        }
    }
    
    class Value<T: Mappable>: Mappable {
        var data: T?
    
        func doSomething() {
    
        }
    }
    
    class Response<T> {
        var value: T?
    }
    
    func handleResponse<  T:Value<User>>(response:Response<T>, completeHandler: (User?, NSError?)->())
    {
        completeHandler(response.value!.data, nil)
    }
    
    
    let response = Response<Value<User>>()
    response.value = Value<User>()
    response.value?.data = User()
    
    
    handleResponse(response, completeHandler:{(r,e) in
        print(r)
    })
    

    【讨论】:

    • 感谢您的回复。实际上我想做的是让 handleResponse 能够处理任何 Mappable 数据,我已经更新了我的代码,希望这可以告诉更多我试图实现的目标。
    猜你喜欢
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多