I am trying to get field values from an interface in Golang. The interface is initially an empty interface which is getting its values from a database result. The DB query is working fine.
The only thing I need is that I need to get the field value of the interface. Here is my code:
s := reflect.ValueOf(t)
for i := 0; i < s.Len(); i++ {
fmt.Println(s.Index(i))
}
where t is an interface having following values:
map[id:null count:1]
I want value of "count"
like simply 1.
My problem is that the Index() method is returning a panic because it needs a struct and I dont have any struct here. So what should I do to get interface value? Is there any solution to iterate over an interface to get field values with or without Golang's reflection package?
Edit
After getting the value for count I need to parse it to json.
Here is my code:
type ResponseControllerList struct{
Code int `json:"code"`
ApiStatus int `json:"api_status"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
TotalRecord interface{} `json:"total_record,omitempty"`
}
response := ResponseControllerList{}
ratingsCount := reflect.ValueOf(ratingsCountInterface).MapIndex(reflect.ValueOf("count"))
fmt.Println(ratingsCount)
response = ResponseControllerList{
200,
1,
"success",
nil,
ratingsCount,
}
GetResponseList(c, response)
func GetResponseList(c *gin.Context, response ResponseControllerList) {
c.JSON(200, gin.H{
"response": response,
})
}
The above code is being used to get the ratingCount
in JSON format to use this response as API response. In this code, I am using the GIN framework to make HTTP request to API.
Now the problem is that when I am printing the variable ratingsCount
, its displaying the exact value of count in terminal what I need. But when I am passing it to JSON, the same variable gives me the response like:
{
"response": {
"code": 200,
"api_status": 1,
"message": "Success",
"total_record": {
"flag": 148
}
}
}
What is the way to get the count's actual value in JSON ?
You put a set of methods into an interface, but you are unable to specify any fields that would be required on anything that implements that interface.
interface{} means you can put value of any type, including your own custom type. All types in Go satisfy an empty interface ( interface{} is an empty interface). In your example, Msg field can have value of any type.
Structs and interfaces are Go's way of organizing methods and data handling. Where structs define the fields of an object, like a Person's first and last name. The interfaces define the methods; e.g. formatting and returning a Person's full name.
Declaring Interface Types Interface describes all the methods of a method set and provides the signatures for each method. To create interface use interface keyword, followed by curly braces containing a list of method names, along with any parameters or return values the methods are expected to have.
But you are allowed to create a variable of an interface type and this variable can be assigned with a concrete type value that has the methods the interface requires. Or in other words, the interface is a collection of methods as well as it is a custom type. To read more about Interfaces, please refer to the article Interface in Golang
Declaring an interface in GoLang An interface is declared as a type. Here is the declaration that is used to declare an interface. type interfaceName interface {}
Now MyString is said to implement the interface VowelsFinder. This is quite different from other languages like Java where a class has to explicitly state that it implements an interface using the implements keyword. This is not needed in Go and Go interfaces are implemented implicitly if a type contains all the methods declared in the interface.
Type Switch: In Go interface, type switch is used to compare the concrete type of an interface with the multiple types provide in the case statements. It is similar to type assertion with only one difference, i.e, case specifies types, not the values. You can also compare a type to the interface type.
You can use type assertion instead of reflection. It is generally better to avoid reflection whenever you can.
m, ok := t.(map[string]interface{})
if !ok {
return fmt.Errorf("want type map[string]interface{}; got %T", t)
}
for k, v := range m {
fmt.Println(k, "=>", v)
}
If you really want to use reflection, you can do something like this:
s := reflect.ValueOf(t)
for _, k := range s.MapKeys() {
fmt.Println(s.MapIndex(k))
}
Update to reply to your latest update
It does not return what you expect because it returns a reflect.Value
. If you want an integer value, you have to use ratingsCount.Int()
.
But as I said before, don't use reflection. Use the first solution with type assertion and just get the count with m["count"]
.
I posted working example there using type assertion: https://play.golang.org/p/9gzwtJIfd7
This is my solution
type Header struct {
Token string
}
type Request struct {
Header
}
func requestedToken(request interface{}) string {
requestValue := reflect.ValueOf(request)
header := requestValue.FieldByName("Header")
if header.Kind() == 0 {
return ""
}
token := header.FieldByName("Token")
if token.Kind() == 0 {
return ""
}
return token.String()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With