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中文網其他相關文章!