简体   繁体   English

在 Golang 中传递结构类型?

[英]Passing a struct Type in Golang?

Please forgive my question, I'm new to Golang and possibly have the wrong approach.请原谅我的问题,我是 Golang 的新手,可能有错误的方法。

I'm currently implementing a Terraform provider for an internal service.我目前正在为内部服务实施 Terraform 提供程序。

As probably expected, that requires unmarshalling JSON data in to pre-defined Struct Types, eg:正如预期的那样,这需要将 JSON 数据解组为预定义的结构类型,例如:

type SomeTypeIveDefined struct {
    ID   string `json:"id"`
    Name String `json:"name"`
}

I've got myself in to a situation where I have a lot of duplicate code that looks like this我让自己陷入了这样一种情况,我有很多重复的代码,看起来像这样

    res := r.(*http.Response)
    var tempThing SomeTypeIveDefined
    dec := json.NewDecoder(res.Body)
    err := dec.Decode(&tempThing)

In an effort to reduce duplication, I decided what I wanted to do was create a function which does the JSON unmarshalling, but takes in the Struct Type as a parameter.为了减少重复,我决定我想做的是创建一个 function 来执行 JSON 解组,但将结构类型作为参数。

I've trawled through several StackOverflow articles and Google Groups trying to make sense of some of the answers around using the reflect package , but I've not had much success in using it.我浏览了几篇 StackOverflow 文章和 Google Groups 试图理解使用反射 package的一些答案,但我在使用它方面没有取得太大成功。

My latest attempt was using reflect.StructOf and passing in a set of StructField s, but that still seems to require using myReflectedStruct.Field(0) rather than myReflectedStruct.ID .我最近的尝试是使用reflect.StructOf并传入一组StructField ,但这似乎仍然需要使用myReflectedStruct.Field(0)而不是myReflectedStruct.ID

I suspect there may be no way until something like Generics are widely available in Golang.怀疑在像 Generics 这样的东西在 Golang 中广泛使用之前可能没有办法。

I considered perhaps an interface for the structs which requires implementing an unmarshal method, then I could pass the interface to the function and call the unmarshal method.我考虑了可能需要实现解组方法的结构的接口,然后我可以将该接口传递给 function 并调用解组方法。 But then I'm still implementing unmarshal on all the structs anyway.但无论如何,我仍然在所有结构上实施解组。

I'm just wondering what suggestions there may be for achieving what I'm after, please?我只是想知道有什么建议可以实现我所追求的,好吗?

Create a helper function with the repeated code.使用重复的代码创建一个助手 function。 Pass the destination value as a pointer.将目标值作为指针传递。

func decode(r *http.Repsonse, v interface{}) error {
     return json.NewDecoder(res.Body).Decode(v)
}

Call the helper function with a pointer to your thing:使用指向您的事物的指针调用助手 function:

var tempThing SomeTypeIveDefined
err := deocde(r, &tempThing)

You can do this with interfaces:您可以使用接口执行此操作:

func decodeResponse(r *http.Response, dest interface{}) error {
    dec := json.NewDecoder(r.Body)
    return dec.Decode(dest)
}

func handler(...) {
    res := r.(*http.Response)
    var tempThing SomeTypeIveDefined
    if err:=decodeResponse(res,&tempThing); err!=nil {
      // handle err
    }
   ...
}

You don't need to implement an unmarshal for the structs, because the stdlib decoder will use reflection to set the struct fields.您不需要为结构实现解组,因为 stdlib 解码器将使用反射来设置结构字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM