简体   繁体   English

在Swift中比较通用对象

[英]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. 我正在上Java的数据结构课程,以帮助自己学习Swift。我正在尝试完成与在Java中使用Swift所做的相同任务。 I am having some trouble comparing Objects in Swift. 我在比较Swift中的对象时遇到了一些麻烦。 In Java, I have the following ArrayList Class with a remove(E obj) method: 在Java中,我具有以下带有remove(E obj)方法的ArrayList类:

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. 这将遍历列表,并将列表中的每个元素强制转换为Comparable并将其与对象进行比较。

Now, translating this into Swift I created the a ArrayLinearList structure and made this function 现在,将其翻译成Swift,我创建了一个ArrayLinearList结构并实现了此功能

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. 我在线阅读了Comparable and Equatable接口上的文档,但据我了解,Comparable and Equatable接口的实现应在要使用的实际类中。 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. 您只需要遵守E型的Equatable协议,它就可以正常工作。 Generic types in swift can adhere to protocols in order to make sure that the type you are passing can do certain operations. swift中的泛型类型可以遵循协议,以确保您传递的类型可以执行某些操作。 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". 您只需要注意两件事就可以相等,因此拥有<E: Equatable>足以告诉编译器“嘿,此函数可用于实现Equatable接口的所有类型”。 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. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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