首頁 >後端開發 >Golang >結構體切片! =它實現的介面切片?

結構體切片! =它實現的介面切片?

PHPz
PHPz轉載
2024-02-09 13:03:08437瀏覽

結構體切片! =它實現的介面切片?

php小編蘋果在這裡為大家揭開一個有關結構體切片的謎題:結構體切片與它實現的介面切片之間的差別是什麼?在Go語言中,切片是一種方便且靈活的資料結構,可以動態改變大小。而結構體切片則是切片的一種特殊形式,它儲存的是結構體類型的元素。但是,它與實現了相同介面的切片之間有何不同?讓我們一起來揭曉答案。

問題內容

我有一個介面Model,它是由struct Person實現的。

為了取得模型實例,我有以下輔助函數:

func newModel(c string) Model {
    switch c {
    case "person":
        return newPerson()
    }
    return nil
}

func newPerson() *Person {
    return &Person{}
}

上述方法允許我傳回一個正確類型的 Person 實例(稍後可以使用相同的方法輕鬆新增模型)。

當我嘗試執行類似的操作來返回模型切片時,出現錯誤。程式碼:

func newModels(c string) []Model {
    switch c {
    case "person":
        return newPersons()
    }
    return nil
}

func newPersons() *[]Person {
    var models []Person
    return &models
}

Go 抱怨: 無法使用 newPersons()(型別 []Person)作為傳回參數中的型別 []Model

#

我的目標是傳回請求的任何模型類型的切片(無論是[]Person[]FutureModel[]Terminator2000

# e)。我缺少什麼,如何正確實施這樣的解決方案?

解決方法

這與我剛剛回答的問題非常相似:https://www.php.cn/link/2c029952e202c0e560626a4c5980d64c

##

簡短的回答是你是對的。結構體的切片不等於結構體實現的介面的切片。

[]Person[]Model 有不同的記憶體佈局。這是因為它們所屬的類型具有不同的記憶體佈局。 Model 是一個介面值,這意味著在記憶體中它的大小為兩個字。一個詞代表類型訊息,另一個詞代表數據。 Person 是一個結構,其大小取決於它包含的欄位。為了從 []Person 轉換為 []Model

,您需要循環數組並對每個元素進行類型轉換。

由於此轉換是一個 O(n) 操作並且會導致建立一個新切片,因此 Go 拒絕隱含執行此操作。您可以使用以下程式碼明確地執行此操作。

models := make([]Model, len(persons))
for i, v := range persons {
    models[i] = Model(v)
}
return models
正如 dskinner 指出的

,您很可能需要一個指標切片,而不是指向切片的指標。通常不需要指向切片的指標。 ###
*[]Person        // pointer to slice
[]*Person        // slice of pointers

以上是結構體切片! =它實現的介面切片?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除