【问题标题】:Access struct values inside an interface访问接口内的结构值
【发布时间】:2021-07-08 10:53:47
【问题描述】:

我有一个类似的界面{} -

Rows interface{}

Rows 界面中,我放置了 ProductResponse 结构体。

type ProductResponse struct {
    CompanyName     string                        `json:"company_name"`
    CompanyID       uint                          `json:"company_id"`
    CompanyProducts []*Products                   `json:"CompanyProducts"`
}
type Products struct {
    Product_ID          uint      `json:"id"`
    Product_Name        string    `json:"product_name"`
}

我想访问 Product_Name 值。如何访问这个。 我可以使用“reflect”pkg 访问外部值(CompanyName、CompanyID)。

value := reflect.ValueOf(response)
CompanyName := value.FieldByName("CompanyName").Interface().(string)

我无法访问 Products 结构值。该怎么做?

【问题讨论】:

  • 不要过多使用空接口。看看 Rob Pike 的“围棋谚语”
  • 这是代码异味。接口描述的是行为,而不是数据。更好的方法是将 getter 方法添加到您的接口(例如type Rows interface{ CompanyProducts() []*Products },然后让您的ProductResponse 结构满足该接口(在实现中,只需返回结构字段)。

标签: go struct interface


【解决方案1】:

你可以使用type assertion:

pr := rows.(ProductResponse)
fmt.Println(pr.CompanyProducts[0].Product_ID)
fmt.Println(pr.CompanyProducts[0].Product_Name)

或者您可以使用reflect 包:

rv := reflect.ValueOf(rows)

// get the value of the CompanyProducts field
v := rv.FieldByName("CompanyProducts")
// that value is a slice, so use .Index(N) to get the Nth element in that slice
v = v.Index(0)
// the elements are of type *Product so use .Elem() to dereference the pointer and get the struct value
v = v.Elem()

fmt.Println(v.FieldByName("Product_ID").Interface())
fmt.Println(v.FieldByName("Product_Name").Interface())

https://play.golang.org/p/RAcCwj843nM

【讨论】:

    【解决方案2】:

    您应该使用类型断言,而不是使用反射。

    res, ok := response.(ProductResponse) 
    if ok { // Successful
       res.CompanyProducts[0].Product_Name // Access Product_Name or Product_ID
    } else {
       // Handle type assertion failure 
    }
    

    【讨论】:

      【解决方案3】:

      您可以访问Product_Name 值,甚至无需使用“反射”pkg,只需使用CompanyProducts 循环遍历CompanyProducts 切片。我为您创建了一个简单的程序,如下所示:

      package main
      
      import (
          "fmt"
      )
      
      type ProductResponse struct {
          CompanyName     string      `json:"company_name"`
          CompanyID       uint        `json:"company_id"`
          CompanyProducts []*Products `json:"CompanyProducts"`
      }
      type Products struct {
          Product_ID   uint   `json:"id"`
          Product_Name string `json:"product_name"`
      }
      
      func main() {
      
          var rows2 interface{} = ProductResponse{CompanyName: "Zensar", CompanyID: 1001, CompanyProducts: []*Products{{1, "prod1"}, {2, "prod2"}, {3, "prod3"}}}
      
          for i := 0; i < len(rows2.(ProductResponse).CompanyProducts); i++ {
              fmt.Println(rows2.(ProductResponse).CompanyProducts[i].Product_Name)
          }
      
      }
      

      输出:

      prod1
      prod2
      prod3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-15
        • 1970-01-01
        • 2021-07-24
        • 1970-01-01
        • 2010-12-20
        • 1970-01-01
        • 2016-09-10
        • 2022-09-22
        相关资源
        最近更新 更多