Vous ne pouvez pas écrire une méthode sur un type générique qui est plus restrictif sur le modèle.
REMARQUE : à partir de Swift 2.0, vous pouvez maintenant écrire des méthodes qui sont plus restrictives sur le modèle. Si vous avez mis à niveau votre code vers 2.0, consultez les autres réponses ci-dessous pour de nouvelles options pour implémenter cela à l'aide d'extensions.
La raison pour laquelle vous obtenez l'erreur 'T' is not convertible to 'T'
est que vous définissez en fait un nouveau T dans votre méthode qui n'est pas du tout lié au T. d'origine. Si vous souhaitez utiliser T dans votre méthode, vous pouvez le faire sans le spécifier dans votre méthode.
La raison pour laquelle vous obtenez la deuxième erreur 'AnyObject' is not convertible to 'T'
est que toutes les valeurs possibles pour T ne sont pas toutes des classes. Pour qu'une instance soit convertie en AnyObject, il doit s'agir d'une classe (ce ne peut pas être une structure, une énumération, etc.).
Votre meilleur pari est d'en faire une fonction qui accepte le tableau comme argument:
func removeObject<T : Equatable>(object: T, inout fromArray array: [T]) {
}
Ou au lieu de modifier le tableau d'origine, vous pouvez rendre votre méthode plus sûre pour les threads et réutilisable en renvoyant une copie:
func arrayRemovingObject<T : Equatable>(object: T, fromArray array: [T]) -> [T] {
}
Comme alternative que je ne recommande pas, vous pouvez faire échouer votre méthode en silence si le type stocké dans le tableau ne peut pas être converti en modèle de méthodes (qui peut être égalisé). (Pour plus de clarté, j'utilise U au lieu de T pour le modèle de la méthode):
extension Array {
mutating func removeObject<U: Equatable>(object: U) {
var index: Int?
for (idx, objectToCompare) in enumerate(self) {
if let to = objectToCompare as? U {
if object == to {
index = idx
}
}
}
if(index != nil) {
self.removeAtIndex(index!)
}
}
}
var list = [1,2,3]
list.removeObject(2) // Successfully removes 2 because types matched
list.removeObject("3") // fails silently to remove anything because the types don't match
list // [1, 3]
Edit Pour surmonter l'échec silencieux, vous pouvez renvoyer le succès sous forme de valeur booléenne:
extension Array {
mutating func removeObject<U: Equatable>(object: U) -> Bool {
for (idx, objectToCompare) in self.enumerate() { //in old swift use enumerate(self)
if let to = objectToCompare as? U {
if object == to {
self.removeAtIndex(idx)
return true
}
}
}
return false
}
}
var list = [1,2,3,2]
list.removeObject(2)
list
list.removeObject(2)
list
T where
de votre déclaration de méthode. Tellement justefunc removeObject<T: Equatable>
. Cette question est liée: stackoverflow.com/questions/24091046/…