在Swift中比较通用对象

时间:2015-03-28 04:49:27

标签: swift object

我正在学习Java数据结构课程并帮助自己学习Swift我正在尝试完成我在Swift中用Java完成的相同作业。我在比较Swift中的Objects时遇到了一些麻烦。在Java中,我有以下ArrayList类和remove(E obj)方法:

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和Equatable接口的文档,但我的理解是Comparable和Equatable接口的实现应该在实际的类中使用。在这一行

if storage[i] == obj {

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

设置它的正确方法是什么,这样我可以比较结构中的通用对象?如果它很重要,通用数组声明为:

var storage = [E]()

1 个答案:

答案 0 :(得分:2)

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

以下是我为摆脱警告所做的工作。

E

至于与协议接口的混淆,因为您没有定义自己的类型,所以不需要实现这些接口。你只关心两件事情是平等的,所以让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>接口的所有类型”。如果要使用您创建的自定义类型并比较两个实例,则需要实现该类型的接口。

希望有所帮助。