Swift Array.insert generics

func getIndex<T: Equatable>(valueToFind: T) -> Int? {...} mutating func replaceObjectWithObject<T: Equatable>(obj1: T, obj2: T) { if let index = self.getIndex(obj1) { self.removeAtIndex(index) self.insert(obj2, atIndex: index) // Error here: 'T' is not convertible to 'T' } } 

I have this function, which is supposed to replace an element with another element. But I am not very familiar with Generics and do not know why this does not work. Please, help.

If I remove Equatable from the mutating function, the error message will move to the first line in this func, and if I then replace it with func find() , it will give me the same error as in line 3.

+5
source share
5 answers

This cannot be done with an extension within the existing protocol and generic system in Swift - you cannot add additional restrictions to a universal subtype of a type, so you cannot extend Array with a method that requires its contents to be Equatable .

You can see this restriction in action with the built-in array type - there is no myArray.find(element) method, but there is a global find() function that accepts a collection and an element with a common restriction that the collection is Equatable elements:

 func find<C : CollectionType where C.Generator.Element : Equatable>(domain: C, value: C.Generator.Element) -> C.Index? 

You can do this for your method - you just need to write a similar top-level function:

 func replaceObjectWithObject<C : RangeReplaceableCollectionType where C.Generator.Element : Equatable>(inout collection: C, obj1: C.Generator.Element, obj2: C.Generator.Element) { if let index = find(collection, obj1) { removeAtIndex(&collection, index) insert(&collection, obj2, atIndex: index) } } var myArray = [1, 2, 3, 4, 5] replaceObjectWithObject(&myArray, 2, 7) // 1, 2, 7, 4, 5 
+4
source

How did you declare the Array extension? The problem is that your common functions require arguments of type Equatable , but when you declared the array, you specified a specific implementation of the Equatable class, such as String . A T not a String without casting.

0
source

What you are trying to do cannot be done using class / structure functions - @Nate Cook provided a very good solution using a global function.

By the way, the reason why it does not work becomes clearer if in your extension methods you replace T with V : they are different. This also explains why the same error occurs if you remove the Equatable : the array contains objects of type T , but you are trying to insert a value of V

0
source

This answer for a duplicate question told her: Create a quick array extension for typed arrays.

There is a way to solve array extensions that apply only to a specific type of array. But you must use Array with elements of type Any, which are Swift workarounds. But the code still works, even if there are other types of elements in the array. See the example below.

 class Job { var name: String var id: Int var completed: Bool init(name: String, id: Int, completed: Bool) { self.name = name self.id = id self.completed = completed } } var jobs: [Any] = [ Job(name: "Carpenter", id: 32, completed: true), Job(name: "Engineer", id: 123, completed: false), Job(name: "Pilot", id: 332, completed: true)] extension Array { // These methods are intended for arrays that contain instances of Job func withId(id: Int) -> Job? { for j in self { if (j as? Job)?.id == id { return j as? Job } } return nil } func thatAreCompleted() -> [Job] { let completedJobs = self.filter { ($0 as? Job) != nil && ($0 as? Job)!.completed} return completedJobs.map { $0 as! Job } } } jobs.withId(332) println(jobs.withId(332)?.name) //prints "Optional("Pilot")" let completedJobs = jobs.thatAreCompleted().map {$0.name} println(completedJobs) //prints "[Carpenter, Pilot]" 
0
source

You can use the extension with the where clause restriction, and I am using Xcode 7.3.1

 extension Array where Element: Equatable { func testEqutability() { let e1 = self[0] let e2 = self[1] if e1 == e2 {//now we can use == to test Element equtability //do something } } } 
0
source

Source: https://habr.com/ru/post/1201664/


All Articles