简体   繁体   中英

Comparing Generic Objects in Swift

I am taking a Data Structures course in Java and to help myself learn Swift I am trying to complete the same assignments I have already done in Java in Swift. I am having some trouble comparing Objects in Swift. In Java, I have the following ArrayList Class with a remove(E obj) method:

public E remove(E obj) {
        if (currentSize == 0){
            return null;
        }
        for (int i=0; i<currentSize; i++)
            if (((Comparable<E>)storage[i]).compareTo(obj) == 0) {
                E removedElement = storage[i];
                for (int j = i;j<currentSize-1;j++) {
                    storage[j] = storage[j+1];
                }
                currentSize--;
                if (currentSize < 0.25*maxSize)
                    shrinkStorage();
                return removedElement;
            }
        return null;
    } 

This goes through the list and casts each element in the list to Comparable and compares it to the object.

Now, translating this into Swift I created the a ArrayLinearList structure and made this function

mutating func remove(obj: E) -> E? {
        if currentSize == 0 {
            return nil
        }
        for var i = 0; i < currentSize; i++ {
            if storage[i] == obj {
                let removedElement = storage[i]
                for var j = 1; j < currentSize-1; j++ {
                    storage[j] = storage[j+1]
                }
                currentSize--
                if currentSize < maxSize/4 {
                    shrinkStorage()
                }
                return removedElement
            }
        }
        return nil
    }

I read the documentation on the Comparable and Equatable interface online but it was my understanding that the implementation of the Comparable and Equatable interface should be in the actual class to be used. on this line

if storage[i] == obj {

Cannot invoke '==' with an argument list of type '($T6,E)'

What is the proper way to set this up so I can compare generic objects in my structure? In case it is important, the generic array is declared as:

var storage = [E]()

Well you almost had it. You just need to adhere to the Equatable protocol for type E and it should all work fine. Generic types in swift can adhere to protocols in order to make sure that the type you are passing can do certain operations. In this case be compared. This is good since you will not be able to use your struct with types that don't adhere to the protocol which will reduce runtime errors due to unexpected methods.

Here is what I did to get rid of the warning.

struct ArrayLinearList<E: Equatable> {

    var currentSize = 0;
    var maxSize = 10;
    var storage = [E]();

    mutating func remove(obj: E) -> E? {

        if currentSize == 0 {
            return nil
        }

        for var i = 0; i < currentSize; i++ {
            if storage[i] == obj {
                let removedElement = storage[i]

                for var j = 1; j < currentSize-1; j++ {
                    storage[j] = storage[j+1]
                }

                currentSize--

                if currentSize < maxSize/4 {
                    shrinkStorage()
                }

                return removedElement

            }

        }

        return nil

    }

    func shrinkStorage() {

    }
}

As for the confusion with the protocol interfaces, since you are not defining your own type you don't need to implement these interface. You just care that two things can be equal so having <E: Equatable> is enough to tell the compiler "hey, this function works with all types that have implemented the Equatable interface". If you want to use a custom type that you create and compare two instances then you will need to implement the interface for that type.

Hope that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM