2

I have an interface{} that is similar like -

Rows interface{}

In the Rows interface i put ProductResponse struct.

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"`
}

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

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

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

2
  • Don’t use empty interface too much. Look at “Go proverbs” by Rob Pike Commented Jul 9, 2021 at 7:55
  • This is a code smell. Interfaces describe behaviour, not data. A better approach would be to add getter methods to your interface (e.g. type Rows interface{ CompanyProducts() []*Products }, and then have your ProductResponse struct satisfy that interface (and in the implementation, just return the struct field). Commented Jul 19, 2021 at 13:09

3 Answers 3

7

You can use type assertion:

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

Or you can use the reflect package:

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

Sign up to request clarification or add additional context in comments.

Comments

3

Instead of using reflection you should use type assertion.

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

Comments

1

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:

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

}

Output:

prod1
prod2
prod3

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.