在接口内部访问结构体的值

huangapple go评论113阅读模式
英文:

Access struct values inside an interface

问题

我有一个类似的interface{},如下所示:

  1. Rows interface{}

Rows接口中,我放置了ProductResponse结构体。

  1. type ProductResponse struct {
  2. CompanyName string `json:"company_name"`
  3. CompanyID uint `json:"company_id"`
  4. CompanyProducts []*Products `json:"CompanyProducts"`
  5. }
  6. type Products struct {
  7. Product_ID uint `json:"id"`
  8. Product_Name string `json:"product_name"`
  9. }

我想要访问Product_Name的值。如何访问呢?
我可以通过使用reflect包来访问外部的值(CompanyName,CompanyID)。

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

我无法访问Products结构体的值。如何做到这一点?

英文:

I have an interface{} that is similar like -

  1. Rows interface{}

In the Rows interface i put ProductResponse struct.

  1. type ProductResponse struct {
  2. CompanyName string `json:"company_name"`
  3. CompanyID uint `json:"company_id"`
  4. CompanyProducts []*Products `json:"CompanyProducts"`
  5. }
  6. type Products struct {
  7. Product_ID uint `json:"id"`
  8. Product_Name string `json:"product_name"`
  9. }

I want to access Product_Name value. How to access this.
I can access outside values (CompanyName , CompanyID) by using "reflect" pkg.

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

I am not able to access Products struct values. How to do that?

答案1

得分: 7

你可以使用type assertion

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

或者你可以使用reflect包:

  1. rv := reflect.ValueOf(rows)
  2. // 获取CompanyProducts字段的值
  3. v := rv.FieldByName("CompanyProducts")
  4. // 该值是一个切片,所以使用.Index(N)获取该切片中的第N个元素
  5. v = v.Index(0)
  6. // 元素的类型是*Product,所以使用.Elem()取消引用指针并获取结构体值
  7. v = v.Elem()
  8. fmt.Println(v.FieldByName("Product_ID").Interface())
  9. fmt.Println(v.FieldByName("Product_Name").Interface())

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

英文:

You can use type assertion:

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

Or you can use the reflect package:

  1. rv := reflect.ValueOf(rows)
  2. // get the value of the CompanyProducts field
  3. v := rv.FieldByName("CompanyProducts")
  4. // that value is a slice, so use .Index(N) to get the Nth element in that slice
  5. v = v.Index(0)
  6. // the elements are of type *Product so use .Elem() to dereference the pointer and get the struct value
  7. v = v.Elem()
  8. fmt.Println(v.FieldByName("Product_ID").Interface())
  9. fmt.Println(v.FieldByName("Product_Name").Interface())

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

答案2

得分: 3

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

  1. res, ok := response.(ProductResponse)
  2. if ok { // 成功
  3. res.CompanyProducts[0].Product_Name // 访问 Product_Name 或 Product_ID
  4. } else {
  5. // 处理类型断言失败
  6. }
英文:

Instead of using reflection you should use type assertion.

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

答案3

得分: 1

你可以通过使用for循环迭代CompanyProducts切片来访问Product_Name的值,而无需使用"reflect"包。我为你的情景创建了一个简单的程序,如下所示:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type ProductResponse struct {
  6. CompanyName string `json:"company_name"`
  7. CompanyID uint `json:"company_id"`
  8. CompanyProducts []*Products `json:"CompanyProducts"`
  9. }
  10. type Products struct {
  11. Product_ID uint `json:"id"`
  12. Product_Name string `json:"product_name"`
  13. }
  14. func main() {
  15. var rows2 interface{} = ProductResponse{CompanyName: "Zensar", CompanyID: 1001, CompanyProducts: []*Products{{1, "prod1"}, {2, "prod2"}, {3, "prod3"}}}
  16. for i := 0; i < len(rows2.(ProductResponse).CompanyProducts); i++ {
  17. fmt.Println(rows2.(ProductResponse).CompanyProducts[i].Product_Name)
  18. }
  19. }

输出:

  1. prod1
  2. prod2
  3. prod3
英文:

You can access Product_Name value without even using "reflect" pkg by simply iterating over the CompanyProducts slice by using for loop.I have created a simple program for you scenario as follows:

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. )
  5. type ProductResponse struct {
  6. CompanyName string `json:&quot;company_name&quot;`
  7. CompanyID uint `json:&quot;company_id&quot;`
  8. CompanyProducts []*Products `json:&quot;CompanyProducts&quot;`
  9. }
  10. type Products struct {
  11. Product_ID uint `json:&quot;id&quot;`
  12. Product_Name string `json:&quot;product_name&quot;`
  13. }
  14. func main() {
  15. var rows2 interface{} = ProductResponse{CompanyName: &quot;Zensar&quot;, CompanyID: 1001, CompanyProducts: []*Products{{1, &quot;prod1&quot;}, {2, &quot;prod2&quot;}, {3, &quot;prod3&quot;}}}
  16. for i := 0; i &lt; len(rows2.(ProductResponse).CompanyProducts); i++ {
  17. fmt.Println(rows2.(ProductResponse).CompanyProducts[i].Product_Name)
  18. }
  19. }

Output:

  1. prod1
  2. prod2
  3. prod3

huangapple
  • 本文由 发表于 2021年7月8日 18:53:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/68300260.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定