首頁 > 後端開發 > Golang > Golang 中的通用結構/介面列表

Golang 中的通用結構/介面列表

WBOY
發布: 2024-02-13 17:30:11
轉載
543 人瀏覽過

Golang 中的通用结构/接口列表

php小編百草在這篇文章中將為大家介紹Golang中的通用結構/介面清單。 Golang是一種開源的程式語言,具有簡單易學、高效可靠的特點,被廣泛應用於網路程式設計、雲端運算等領域。在Golang中,通用結構和介面是非常重要的概念,可以幫助我們實現程式碼的複用性和擴充性。透過本文的介紹,相信讀者們能夠更好地理解和應用Golang中的通用結構和接口,提升自己的程式設計技能。

問題內容

有沒有辦法在 go 中獲得通用結構/介面的清單?

這就是我想要實現的目標。

<code>package main

type List[T any] struct {
    Elements []T
}

func (f *List[T]) Add(el T) {
    f.Elements = append(f.Elements, el)
}

type ListInterface[T any] interface {
    Add(el T)
}

func main() {
    listOfLists := make([]ListInterface[any], 0)
    listOfLists = append(listOfLists, &List[int]{})
}
</code>
登入後複製

這是我得到的錯誤。

cannot use &List[int]{} (value of type *List[int]) as ListInterface[any] value in argument to append: *List[int] does not implement ListInterface[any] (wrong type for method Add)
    have Add(int)
    want Add(any)
登入後複製

所以,如果我理解正確的話,在 go 中 any# 是它自己的類型。它不是“運行時想要的任何類型”的同義詞。我的問題是,是否有可能做這樣的事情?

解決方法

您在這裡嘗試執行的操作表明您期望 go 的泛型能夠進行類型擦除(就像 Java 泛型一樣)。但事實並非如此。

你有一個 List[int],這表示它的 Add 方法如下所示:

func (l *List) Add(el int) {
    l.Elements = append(l.Elements, el)
}
登入後複製

然後嘗試將其新增至實作該介面的物件切片:

Add(v any)
登入後複製

現在,您可能認為 int 可以用作 any,您是對的,它可以,但是當您看到:

var s []ListInterface[any]
登入後複製

您是說,所述切片中的所有元素都將具有 Add 方法,該方法採用 any 類型的參數,因此這意味著:

s[0].Add("foo")
s[1].Add(123)
登入後複製

應該始終是有效的呼叫。如果 s[0] 的類型為 List[int] (如您的程式碼片段中的情況),則這不成立。您將嘗試將字串附加到 Elements ,其類型為 []int

有一種說法認為應該允許逆向:

s := []ListInterface[int]{}
s = append(s, &List[any]{})
登入後複製

看來 List[any] 將接受 int 參數,但這也是不允許的。在某些情況下這可能很有用,但在許多情況下這可能會出現問題。

本質上,Go 中的泛型是在編譯時處理的事情。當您建立List[int] 時,編譯器會建立一個類似List_int 的類型,並在該類型上實作Add(el int) 方法,與您最終使用的任何其他List 類型相同。這些類型都不會具有 Add(any) 方法,除非您建立 List[any]。將其視為編譯器輔助的樣板程式碼產生。不是運行時類型擦除。

結果: List[int]List[any] 是完全不同的型,因此不能並排坐在切片中,就好像它們是同一型別一樣。如果您希望能夠做您想做的事情,您可以這樣做:

func (l *List[T]) AddAny(v any) {
    tv, ok := v.(T)
    if !ok {
        return // or return an error
    }
    l.Add(tv)
}
登入後複製

採用 any 值的方法,使用類型斷言來查看給定值是否與清單的基礎類型相容,如果是這種情況則會新增它。然後您可以將它們添加到單個切片中,如下所示:

type Lists interface {
    AddAny(any)
}

s := []Lists{}
s = append(s, &List[int]{}, &List[string]{})
s[0].AddAny(123) // will work
s[0].AddAny("foo") // will not, with the current code this will silently fail
s[1].AddAny("foo") // works fine
s[1].AddAny(123) // silently fails
登入後複製

但實際上,當你做這樣的事情時,代碼只是尖叫X-Y 問題,你試圖使用Y(泛型)來解決你的問題,而真正的問題是X:什麼是最好的方法解決問題?

以上是Golang 中的通用結構/介面列表的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板