2016-04-20 4 views
0

J'ai une classe Response contenant une valeur, et j'ai aussi une classe Value qui contient des données conformes au protocole Mappable.Le type de génériques imbriqués Swift n'est pas conforme au protocole.

Maintenant j'ai une fonction pour gérer l'objet Response, mais pendant que j'essaie de sortir les données de l'objet Value, le type "R" n'est pas conforme au protocole.

C'est mon code dans la cour:

Mise à jour

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

Suis-je le fais bien? Ou tout autre moyen pour y parvenir. Merci

Répondre

2

Je ne sais pas vraiment pourquoi votre code ne fonctionne pas. Je suppose que c'est parce que Swift a de la difficulté à inférer le type d'un générique dans un générique.

J'ai réussi à obtenir pour compiler en enveloppant le type response lui-même, plutôt que de définir un nouveau générique pour Value<R>. Par exemple:

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

J'aimerais savoir si quelqu'un d'autre le sait exactement pourquoi votre code d'origine ne fonctionne pas bien!

+0

Oui, définissez la fonction comme ceci fonctionnera. Merci. – desmond0321

+0

Je soupçonne en compilant, en fait, ne pas connaître mes génériques R a conformer le protocole, donc pendant que j'accède aux données dans les génériques T, il suppose que mon R est juste un AnyObject. – desmond0321

0

Heh, en accédant à response.value dans la fonction handleResponse() - bloque réellement le compilateur, c'est un bogue dans le compilateur pour sûr. J'ai réécrit votre code, donc il compile:

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

Merci pour la réponse. En fait, ce que j'essaie de faire est de rendre handleResponse capable de gérer toutes les données Mappable, j'ai mis à jour mon code, j'espère que cela peut dire plus ce que j'essaie d'atteindre. – desmond0321