Nie można napisać metody w typie ogólnym, który jest bardziej restrykcyjny w szablonie.
UWAGA : od wersji Swift 2.0 możesz teraz pisać metody, które są bardziej restrykcyjne w szablonie. Jeśli zaktualizowałeś swój kod do wersji 2.0, zapoznaj się z innymi odpowiedziami poniżej, aby poznać nowe opcje implementacji tego za pomocą rozszerzeń.
Powodem, dla którego otrzymujesz błąd, 'T' is not convertible to 'T'
jest to, że w rzeczywistości definiujesz nowe T w swojej metodzie, które nie jest w ogóle związane z oryginalnym T. Jeśli chcesz użyć T w swojej metodzie, możesz to zrobić bez określania go w swojej metodzie.
Powodem drugiego błędu 'AnyObject' is not convertible to 'T'
jest to, że nie wszystkie możliwe wartości T są klasami. Aby instancja została przekonwertowana na AnyObject, musi być klasą (nie może to być struktura, wyliczenie itp.).
Najlepszym rozwiązaniem jest uczynienie z niej funkcji akceptującej tablicę jako argument:
func removeObject<T : Equatable>(object: T, inout fromArray array: [T]) {
}
Zamiast modyfikować oryginalną tablicę, możesz uczynić swoją metodę bardziej bezpieczną dla wątków i wielokrotnego użytku, zwracając kopię:
func arrayRemovingObject<T : Equatable>(object: T, fromArray array: [T]) -> [T] {
}
Alternatywą, której nie polecam, może być cicha awaria metody, jeśli typ przechowywany w tablicy nie może zostać przekonwertowany na szablon metod (jest to równoważne). (Dla jasności używam U zamiast T jako szablonu metody):
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]
Edytuj Aby przezwyciężyć cichą porażkę, możesz zwrócić sukces jako wartość logiczną:
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
z deklaracji metody. Więc po prostufunc removeObject<T: Equatable>
. To pytanie jest powiązane: stackoverflow.com/questions/24091046/…