我已經實作了一個非常簡單的 Decode 方法(gob.Decoder現在使用) - 這適用于單個回應 - 它甚至適用于切片,但我需要實作一個 DecodeMany 方法,它能夠解碼一組單獨的回應(不是一片)。
作業解碼方法:
var v MyType
_ = Decode(&v)
...
func Decode(v interface{}) error {
buf, _ := DoSomething() // func DoSomething() ([]byte, error)
// error handling omitted for brevity
return gob.NewDecoder(bytes.NewReader(buf)).Decode(v)
}
我試圖為 DecodeMany 方法做的是處理不一定是切片的回應:
var vv []MyType
_ = DecodeMany(&vv)
...
func DecodeMany(vv []interface{}) error {
for _, g := range DoSomething() { // func DoSomething() []struct{Buf []bytes}
// Use g.Buf as an individual "interface{}"
// want something like:
var v interface{} /* Somehow create instance of single vv type? */
_ = gob.NewDecoder(bytes.NewReader(g.Buf)).Decode(v)
vv = append(vv, v)
}
return
}
除了不編譯上面還有以下錯誤:
不能在 DecodeMany 的引數中使用 &vv(*[]MyType 型別的值)作為型別 []interface{}
uj5u.com熱心網友回復:
如果你想修改傳入的切片,它必須是一個指標,否則你必須回傳一個新的切片。此外,如果函式被宣告為具有 type 的引數[]interface{},則只能傳遞 type 的值而不能傳遞[]interface{}其他切片型別...除非您使用泛型...
這是開始使用 Go 1.18 中引入的泛型的完美示例。
更改DecodeMany()為泛型,T型別引數為切片元素型別:
取指標時
func DecodeMany[T any](vv *[]T) error {
for _, g := range DoSomething() {
var v T
if err := gob.NewDecoder(bytes.NewReader(g.Buf)).Decode(&v); err != nil {
return err
}
*vv = append(*vv, v)
}
return nil
}
這是一個簡單的應用程式來測驗它:
type MyType struct {
S int64
}
func main() {
var vv []MyType
if err := DecodeMany(&vv); err != nil {
panic(err)
}
fmt.Println(vv)
}
func DoSomething() (result []struct{ Buf []byte }) {
for i := 3; i < 6; i {
buf := &bytes.Buffer{}
v := MyType{S: int64(i)}
if err := gob.NewEncoder(buf).Encode(v); err != nil {
panic(err)
}
result = append(result, struct{ Buf []byte }{buf.Bytes()})
}
return
}
這個輸出(在Go Playground上試試):
[{3} {4} {5}]
回傳切片時
如果選擇回傳切片,則不必傳遞任何內容,但需要分配結果:
func DecodeMany[T any]() ([]T, error) {
var result []T
for _, g := range DoSomething() {
var v T
if err := gob.NewDecoder(bytes.NewReader(g.Buf)).Decode(&v); err != nil {
return result, err
}
result = append(result, v)
}
return result, nil
}
使用它:
vv, err := DecodeMany[MyType]()
if err != nil {
panic(err)
}
fmt.Println(vv)
在Go Playground上試試這個。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/457419.html
