Reputation: 7969
I've a struct called item
type Item struct {
Limit int
Skip int
Fields string
}
item := Item {
Limit: 3,
Skip: 5,
Fields: "Valuie",
}
how could I get the field name, value and join it into a string.
something like:
item := Item {
Limit: 3,
Skip: 5,
Fields: "Valuie",
}
to a string something like
"Limit=3&Skip=5&Fields=Valuie"
And I've try reflections to get convert interface to field value map so far. Am I going the right way? Cause I think there might have some better solutions. And thanks!
m, _ = reflections.Items(data)
for k, v := range m {
fmt.Printf("%s : %s\n", k, v)
}
I've got
Limit : %!s(int=3)
Skip : %!s(int=5)
Fields : Valuie
Upvotes: 5
Views: 9739
Reputation: 16395
Take a look at go-querystring. It converts a struct into URL query parameters (your expected output).
type Item struct {
Limit int `limit:"limit"`
Skip int `url:"skip"`
Fields string `url:"fields"`
}
item := Item {
Limit: 3,
Skip: 5,
Fields: "Valuie",
}
v, _ := query.Values(item)
fmt.Print(v.Encode())
// will output: "limit=3&skip=5&fields=Valuie"
Upvotes: 0
Reputation: 58369
There's no need to use reflection for this. Just write out the code for the types you have.
func (i *Item) URLValues() string {
uv := url.Values()
uv.Set("Limit", strconv.Itoa(i.Limit))
uv.Set("Skip", strconv.Itoa(i.Skip))
uv.Set("Fields", i.Fields)
return uv.Encode()
}
This code is simple, readable, and you don't need to think to write it. Unless you have a lot of types that you're going to be converting to values then I'd not even think about the magic reflection-based solution to this problem.
Upvotes: 3
Reputation: 57737
For any struct you can use reflection and url.Values
from the net/url
package:
i := Item{1, 2, "foo"}
v := url.Values{}
ri := reflect.ValueOf(i)
ri.FieldByNameFunc(func(name string) bool {
v.Set(name, fmt.Sprintf("%v", ri.FieldByName(name).Interface()))
return false
})
fmt.Println(v.Encode())
Of course, this code does not handle nested data structures or slices so you would need to extend the code if you use other data structures to make it more general. However, this example should get you started.
Upvotes: 1
Reputation: 121792
You can use %v instead of %s. %s will assume a string, something that can be converted to a string (i.e. byte array) or an object with a String() method. Using %v will check the type and display it correctly.
Example of the String() method call with %s with your example: http://play.golang.org/p/bxE91IaVKj
Upvotes: 10