簡體   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