首頁  >  文章  >  後端開發  >  描述可變結構行為的 Go 類型約束

描述可變結構行為的 Go 類型約束

WBOY
WBOY轉載
2024-02-08 21:15:10655瀏覽

描述可变结构行为的 Go 类型约束

php小編新一今天為大家介紹一種描述可變結構行為的 Go 類型約束。在 Go 語言中,我們可以使用介面類型來定義一組方法的集合,並透過型別約束來限制傳入參數的型別。這種方式可以在編譯時進行類型檢查,確保程式碼的安全性和可靠性。透過合理使用介面類型和類型約束,我們可以實現程式碼的靈活性和可擴充性,提高程式的可維護性和可讀性。接下來,讓我們詳細了解如何使用 Go 類型約束來描述可變結構行為。

問題內容

我想定義一個通用函數,其中類型約束描述可變結構行為。

我所說的「可變行為」是這樣的介面:

type Unmarshaler interface {
    Unmarshal(data []byte) error
}

...實作看起來像這樣:

type Foo struct {
    Content string
}

func (f *Foo) Unmarshal(data []byte) error {
    f.Content = string(data)
    return nil
}

呼叫介面方法會改變結構。

我想要做的是定義一個通用函數,其中類型約束是上面的介面。泛型函數負責初始化具體類型的實例,然後使用介面方法對其進行變異並傳回。

func Unmarshal[T Unmarshaler](data []byte) (T, error) {
    var m T
    return m, m.Unmarshal(data)
}

所以我希望能夠使用 Foo 類型來呼叫該泛型函數。

func main() {
    foo, err := Unmarshal[*Foo]([]byte("hello"))
    if err == nil {
        log.Println(foo.Content) // hello
    } else {
        log.Fatal(err)
    }
}

我必須傳遞 *Foo 作為類型參數,因為只有指向 Foo 的指標才實作 Unmarshaler 介面。但是,當 Foo 的 Unmarshal 方法收到 fnil 值時,就會出現恐慌。這對我來說都是有意義的,因為 var m T 將使指向 Foo 的指標值為零,即 nil。但我不確定我是否已經走進了死胡同?

https://go.dev/play/p/H5s59NWNiDA

#正如我所能描述的那樣,每當我的類型約束描述一些可變的結構行為,並且我的泛型函數想要初始化,然後改變結構的實例時,我都會遇到這個問題。這可能嗎?有更好的方法來建造這個嗎?

解決方法

核心問題是為某些類型 T 建立有用的值。有幾種方法可以做到這一點: m := make(T) (地圖和頻道)等。您可以使用 reflect

套件來建立值,但讓呼叫者將值作為參數傳遞會更簡單。

func Unmarshal[T Unmarshaler](m T, data []byte) (T, error) {
    return m, m.Unmarshal(data)
}

像這樣呼叫函數:

foo, err := Unmarshal(&Foo{}, []byte("hello"))
https://www.php.cn/link/8eb51d0a68e9373df41f88e5b551d4a3

###

以上是描述可變結構行為的 Go 類型約束的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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