1

I have a Response class contain a value, and I also have a Value class contain data which conform to Mappable protocol.

Now I have a function to handle Response object, but while I try to get the data out from Value object, it show Type "R" does not conform to protocol.

This is my code in playground:

Update

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)
})

Am I doing it right? Or any other way to achieve this. Thanks

4

2 回答 2

2

I'm not really sure why your code doesn't work. I assume it's because Swift is having difficulty inferring the type of a generic within a generic.

I managed to get it to compile by wrapping the response type itself, rather than defining a new generic for Value<R>. For example:

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

I would love to know if anyone else knows exactly why your original code doesn't work though!

于 2016-04-20T19:56:54.630 回答
0

Heh, accessing response.value in the handleResponse()-function actually crashes the compiler, thats a bug in the compiler for sure. I rewrote your code, so it compiles:

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)
})
于 2016-04-20T18:02:21.563 回答