繁体   English   中英

在Swift中比较通用对象

[英]Comparing Generic Objects in Swift

我正在上Java的数据结构课程,以帮助自己学习Swift。我正在尝试完成与在Java中使用Swift所做的相同任务。 我在比较Swift中的对象时遇到了一些麻烦。 在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;
    } 

这将遍历列表,并将列表中的每个元素强制转换为Comparable并将其与对象进行比较。

现在,将其翻译成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
    }

我在线阅读了Comparable and Equatable接口上的文档,但据我了解,Comparable and Equatable接口的实现应在要使用的实际类中。 在这条线上

if storage[i] == obj {

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

什么是正确的设置方式,以便可以比较结构中的通用对象? 如果很重要,则将通用数组声明为:

var storage = [E]()

好吧,您几乎拥有了。 您只需要遵守E型的Equatable协议,它就可以正常工作。 swift中的泛型类型可以遵循协议,以确保您传递的类型可以执行某些操作。 在这种情况下进行比较。 这很好,因为您将无法使用不符合协议的类型的结构,这会减少由于意外方法而导致的运行时错误。

这是我摆脱警告的方法。

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() {

    }
}

至于与协议接口的混淆,由于您没有定义自己的类型,因此不需要实现这些接口。 您只需要注意两件事就可以相等,因此拥有<E: Equatable>足以告诉编译器“嘿,此函数可用于实现Equatable接口的所有类型”。 如果要使用创建的自定义类型并比较两个实例,则需要实现该类型的接口。

希望能有所帮助。

暂无
暂无

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

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