首頁  >  文章  >  後端開發  >  泛型:嵌入在介面中的約束和結構

泛型:嵌入在介面中的約束和結構

王林
王林轉載
2024-02-08 23:21:19573瀏覽

泛型:嵌入在介面中的約束和結構

php小編小新為您帶來關於泛型的介紹。泛型是一種嵌入在介面中的約束和結構,它可以讓我們在編寫程式碼時更加靈活和有效率。透過使用泛型,我們可以在編譯時發現並解決類型錯誤,提高程式碼的可讀性和可維護性。泛型還可以幫助我們設計更通用的資料結構和演算法,提升程式碼的重用性。在這篇文章中,我們將深入探討泛型的概念、用法和實際應用,幫助您更能理解和運用泛型程式設計。

問題內容

以下程式碼無法編譯,並報告./main.go:35:7: test does not meet constraint (test missing in main.structwithname)

package main

import "fmt"

type Test struct {
    Name string
}

func (t Test) String() string {
    return fmt.Sprintf("Name: %v", t.Name)
}

type StructWithName struct {
    Name string
}

type Constraint interface {
    StructWithName
    // ~struct {
    //  Name string
    // }
    String() string
}

func Print[T Constraint](x T) {
    //s := T{}
    fmt.Printf("Hello %v", x)
}

func main() {
    t := Test{
        Name: "Test",
    }

    Print(t)
}

但是,如果我註解掉 structwithname 並取消註解 ~struct 區塊,那麼它可以正常編譯。我無法理解兩者之間的語義差異。

我試圖做的是擁有一個可以以通用方式處理結構的通用方法;即 x := s{} 然後將其傳遞給外部庫。在這個例子中,它適用於terraform 提供程序,資源中的代碼非常相似,我對現有提供者中看到的重複量感到有點困擾;就我而言,資源非常相似,有些資源在預設結構之上只有一兩個字段)。我希望能夠編寫一組通用方法來完成所有相似的事情,並且只有其他地方的特殊性(廢話!)。

我還處於 go 之旅的早期階段,我無法理解編譯器錯誤。

解決方法

如果我理解正確的話,你真正想要的東西是不可能的。 go 泛型不支援存取結構體欄位子集。

就所涉及的錯誤而言...

類型的名稱指定類型的標識,並且具有不同名稱(彼此不是別名)的兩個類型始終是不同的,因此teststructwithname 是兩個不同的類型。它們唯一的共同點是它們的底層類型

type constraint 介面{ structwithname } 介面是僅包含一種類型的類型集,即structwithname,並且由於test 不是該類型集的成員,這意味著不可能使用test 類型來滿足該約束。

type struct { name string } 是一個無名型,任何無名型別的底層型別都是該型別本身,也就是struct 的底層型別{ name string } is struct { name string }

約束中類型前面的波形符,即 ~t,表示任何類型,其底層類型t 相同。或者,更準確地說,

~t 形式的項目的類型集合是基礎類型為 t 的所有類型的集合。

所以當你這樣做時

type Constraint interface { ~struct { Name string } }

那麼約束的類型集將包含任何以 struct { name string } 作為其基礎類型的類型。

以上是泛型:嵌入在介面中的約束和結構的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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