Você não pode escrever um método em um tipo genérico mais restritivo no modelo.
NOTA : a partir Swift 2.0, agora você pode escrever métodos que são mais restritivas no modelo. Se você atualizou seu código para 2.0, consulte outras respostas mais abaixo para novas opções para implementar isso usando extensões.
O motivo pelo qual você obteve o erro 'T' is not convertible to 'T'
é que, na verdade, você está definindo um novo T no seu método que não está relacionado ao T. original. Se você deseja usar o T no seu método, pode fazê-lo sem especificá-lo no seu método.
A razão pela qual você obtém o segundo erro 'AnyObject' is not convertible to 'T'
é que nem todos os valores possíveis para T são todas as classes. Para que uma instância seja convertida em AnyObject, ela deve ser uma classe (não pode ser uma estrutura, enumeração etc.).
Sua melhor aposta é torná-la uma função que aceite a matriz como argumento:
func removeObject<T : Equatable>(object: T, inout fromArray array: [T]) {
}
Ou, em vez de modificar a matriz original, você pode tornar seu método mais seguro e reutilizável, retornando uma cópia:
func arrayRemovingObject<T : Equatable>(object: T, fromArray array: [T]) -> [T] {
}
Como uma alternativa que eu não recomendo, você pode fazer com que seu método falhe silenciosamente se o tipo armazenado na matriz não puder ser convertido no modelo de métodos (que é equivalente). (Para maior clareza, estou usando U em vez de T para o modelo do método):
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]
Editar Para superar a falha silenciosa, você pode retornar o sucesso como um bool:
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
declaração do seu método. Tão apenasfunc removeObject<T: Equatable>
. Esta questão está relacionada: stackoverflow.com/questions/24091046/…