I have a RegistrationRequest struct:
type RegistrationRequest struct {
Email *string
Email2 *string
Username *string
Password *string
Name string
}
Where Email2
is the email value entered again to verify that what the user entered is correct.
I also have a User struct:
type User struct {
Email *string
Username *string
Password *string
Name string
}
Of course, there is no need to store Email2
beyond registration.
So I have two variables: req
and u
- one for each struct. Is it possible to assign the req
struct into to the u
struct so that all the common fields will exist in the u
struct?
Using simple assignment you can't because even though the fields of User
are a subset of RegistrationRequest
, they are completely 2 different types, and Assignability rules don't apply.
You could write a function which uses reflection (reflect
package), and would copy all the fields from req
to u
, but that is just ugly (and inefficient).
Best would be to refactor your types, and RegistrationRequest
could embed User
.
Doing so if you have a value of type RegistrationRequest
that means you already also have a value of User
:
type User struct {
Email *string
Username *string
Password *string
Name string
}
type RegistrationRequest struct {
User // Embedding User type
Email2 *string
}
func main() {
req := RegistrationRequest{}
s := "as@as.com"
req.Email = &s
s2 := "testuser"
req.Username = &s2
u := User{}
u = req.User
fmt.Println(*u.Username, *u.Email)
}
Output: (try it on the Go Playground)
testuser as@as.com
Also please note that since your structs contain pointers, when copying a struct
, pointer values will be copied and not pointed values. I'm not sure why you need pointers here, would be best to just declare all fields to be non-pointers.
Also note that embedding is not really a requirement, it just makes your types and their usage more smooth. User
could just as well be an "ordinary" field of RequistrationRequest
, e.g.:
type RegistrationRequest struct {
Usr User // This is just an ordinary field, not embedding
Email2 *string
}
You can use "github.com/jinzhu/copier" package to Copy between structs containing same field name. This package uses reflection to do this.
package main
import (
"fmt"
"github.com/jinzhu/copier"
)
type RegistrationRequest struct {
Email *string
Email2 *string
Username *string
Password *string
Name string
}
type User struct {
Email *string
Username *string
Password *string
Name string
}
func main() {
user := new(User)
req := new(RegistrationRequest)
user.Email, user.Password, user.Username = new(string), new(string), new(string)
user.Name = "John Doe"
*user.Email = "a@b.com"
*user.Password = "1234"
*user.Username = "johndoe"
fmt.Println("User :",user.Name, *user.Email, *user.Username, *user.Password)
copier.Copy(req, user)
fmt.Println("RegistrationRequest :",req.Name, *req.Email, *req.Username, *req.Password)
}
Output
User : John Doe a@b.com johndoe 1234
RegistrationRequest : John Doe a@b.com johndoe 1234