为了账号安全,请及时绑定邮箱和手机立即绑定

Go:为“一组”单个结果实施 ManyDecode

Go:为“一组”单个结果实施 ManyDecode

Go
牧羊人nacy 2022-11-28 10:39:11
我已经实现了一个非常简单的解码方法(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{}
查看完整描述

1 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

如果你想修改传递的切片,它必须是一个指针,否则你必须返回一个新的切片。此外,如果函数被声明为具有 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试试这个。



查看完整回答
反对 回复 2022-11-28
  • 1 回答
  • 0 关注
  • 71 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信