php editor Strawberry will introduce to you a commonly used technique today - Go. This is an idiomatic way of mapping one structure to another. In programming, we often need to convert one data structure into another data structure to meet different needs. Go provides a concise and flexible way to achieve this goal. Whether processing database query results, API responses, or other data transformation scenarios, Go can help us easily complete structure mapping work. Next, let us learn about the specific usage of Go!
I am using a third-party go language library to query the user's ldap database. The library returns a resultuser slice of searchresult which I need to map to my own user structure. These two structures have different field names, I only need specific fields from resultuser. Is there a more idiomatic way in go to convert one struct to another.
I created a demo below (also linked on the go playground). Thank you in advance for any advice you may have for this go newbie!
package main import "fmt" type ( User struct { id int32 firstName string } ResultUser struct { uid int32 fname string } SearchResults []ResultUser ) func main() { results := getSearchResults() users := mapResultsToUsers(results) // <-- This is the problem fmt.Println("User struct:", users[0].id, users[0].firstName) fmt.Println("User struct:", users[1].id, users[1].firstName) } // Simulates a query to a data with a library func getSearchResults() (results SearchResults) { return append(results, ResultUser{1, "John"}, ResultUser{2, "Jane"}) } // Seems like a code smell to have to do this // Is there a more idiomatic way to do this? func mapResultsToUsers(results SearchResults) (users []User) { for _, result := range results { users = append(users, User{result.uid, result.fname}) } return users }
I've seen struct field tags but not sure if there's a better way.
I think what you have is pretty much the best solution, although I would move the mapping into a dedicated function, like:
func fromresultuser(r *resultuser) *user { return &user{ id: r.uid, firstname: r.fname, } }
Then mapresultstousers
becomes:
func mapresultstousers(results searchresults) (users []*user) { for _, result := range results { users = append(users, fromresultuser(result)) } return users }
I've seen struct field tags but not sure if there's a better way.
You can combine something so that you can annotate your user
structure like this:
User struct { id int32 `mappedFrom:"uid"` firstName string `mappedFrom:"fname"` }
But implementing this requires a much more complex approach than fromresultuser
presented here, and requires familiarity with the reflect
package. I think, as one of my colleagues likes to say, "the juice isn't worth the squeeze."
The above is the detailed content of Go - Idiomatic way of mapping one struct to another. For more information, please follow other related articles on the PHP Chinese website!