Search code examples
arraysswiftgenericsequatable

Swift Generic array Equatable casting


I have a class AAA which contains an generic array. Since Item could be not Equatable, so I do not code it as class AAA<Item: Equatable>.

I would like to add an remove function in class AAA which is available when Item is Equatable. By calling this function, it will call a function in the Array Extension.

Since Item is not Equatable by default, the following code is not able to compile.

class AAA<Item>
{
    var items = [Item]()

    func remove(item: Item)
    {
        items.remove(object: item)
    }    
}

extension Array where Element: Equatable
{
    // Remove first collection element that is equal to the given `object`:
    mutating func remove(object: Element)
    {
        if let index = index(of: object)
        {
            remove(at: index)
        }
    }
}

In the next step, I try to convert the items and item into Equatable. However, I cannot find any way to check and cast the items array into a array with Equatable elements.

func remove<ItemEquatable: Item> (item: ItemEquatable) where ItemEquatable: Equatable
{
    items.remove(object: item)
}

Any idea or suggestion? Thanks


Solution

  • To define the function only for AAA<Item> if Item is equatable, simply put the definition into a restricted extension of the class:

    class AAA<Item> {
        var items = [Item]()
    }
    
    extension AAA where Item: Equatable {
    
        func remove(item: Item) {
            items.remove(object: item)
        }
    }
    

    Your approach cannot work because you could still call the remove method on any AAA<Item> instance, without Item being Equatable.

    In other words: You need to restrict the generic type Item of the class, not the type of the argument of remove().