【问题标题】:Passing a struct Type in Golang?在 Golang 中传递结构类型?
【发布时间】:2022-01-02 02:48:37
【问题描述】:

请原谅我的问题,我是 Golang 新手,可能有错误的方法。

我目前正在为内部服务实现 Terraform 提供程序。

正如预期的那样,这需要将 JSON 数据解组为预定义的结构类型,例如:

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

我遇到了这样一种情况,我有很多重复的代码,看起来像这样

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

为了减少重复,我决定创建一个函数来执行 JSON 解组,但将结构类型作为参数。

我翻阅了几篇 StackOverflow 文章和 Google 群组,试图了解有关使用 reflect package 的一些答案,但我在使用它方面没有取得太大成功。

我最近的尝试是使用reflect.StructOf 并传入一组StructFields,但这似乎仍然需要使用myReflectedStruct.Field(0) 而不是myReflectedStruct.ID

怀疑在像泛型这样的东西在 Golang 中广泛使用之前可能没有办法。

我考虑了可能需要实现解组方法的结构的接口,然后我可以将接口传递给函数并调用解组方法。但无论如何,我仍在对所有结构实施解组。

我只是想知道有什么建议可以帮助我实现我的目标?

【问题讨论】:

  • 您所描述的功能如何减少重复?我想不出比单线json.NewDecoder(res.Body).Decode(&tempThing) 更小的版本。您能否为您正在寻找的假设函数提供示例函数签名?
  • @maxm:所以这个问题在某种程度上被简化了,希望它更容易理解和回答。但是解组发生在一个更大的方法中(我没有提到),它也减少了其他重复。但就这个更人为的例子而言,你是对的。从表面上看,它具有边际收益。
  • “为了减少重复,”坏主意。 “我决定我想做的是创建一个执行 JSON 解组的函数,但将结构类型作为参数。”你不能那样做。
  • @Volker 我很好奇你为什么减少重复是一个坏主意。根据我的专业经验,如果有明确的重复,则不重复代码是常见的做法。当然,早期的抽象是一件坏事。就我而言,我有无数完全相同的代码示例。您介意详细说明什么是坏主意吗?

标签: json go reflection unmarshalling


【解决方案1】:

使用重复的代码创建一个辅助函数。将目标值作为指针传递。

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

使用指向你的东西的指针调用辅助函数:

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

【讨论】:

  • 当我读到这篇文章时,我的手掌非常难受。我想我对无法在decode 函数中使用字段名称感到非常着迷,以至于我没有意识到我实际上并不需要。这将满足我的需要,谢谢。
【解决方案2】:

你可以用接口做到这一点:

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
    }
   ...
}

您不需要为结构实现解组,因为 stdlib 解码器将使用反射来设置结构字段。

【讨论】:

  • 与其他答案相同,我在阅读此内容时面面相觑。这正是我需要的。我什至不需要关心解码器函数中使用的字段。非常感谢您指出我的愚蠢。
猜你喜欢
  • 2017-11-29
  • 1970-01-01
  • 2017-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多