Asignar struct con otra estructura

Tengo una estructura RegistrationRequest:

type RegistrationRequest struct { Email *string Email2 *string Username *string Password *string Name string } 

Donde Email2 es el valor del correo electrónico ingresado nuevamente para verificar que lo ingresado por el usuario sea correcto.

También tengo una estructura de usuario:

 type User struct { Email *string Username *string Password *string Name string } 

Por supuesto, no hay necesidad de almacenar Email2 más allá del registro.

Entonces tengo dos variables: req y u – uno para cada estructura. ¿Es posible asignar la estructura de req a la estructura u para que todos los campos comunes existan en la estructura u ?

Con la asignación simple no puede porque aunque los campos de User son un subconjunto de RegistrationRequest , son completamente de 2 tipos diferentes, y las reglas de Asignabilidad no se aplican.

Podrías escribir una función que utilizara la reflexión ( reflect paquete), y copiaría todos los campos de ” req a ” u , pero eso es simplemente feo (e ineficiente).

Lo mejor sería refactorizar sus tipos, y RegistrationRequest podría incrustar User .

Si tiene un valor de tipo RegistrationRequest significa que ya tiene un valor de 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) } 

Salida: (pruébalo en el patio de juegos Go )

 testuser as@as.com 

También tenga en cuenta que dado que sus estructuras contienen punteros, al copiar una struct , los valores del puntero se copiarán y no los valores apuntados. No estoy seguro de por qué necesita punteros aquí, sería mejor simplemente declarar todos los campos como no punteros.

También tenga en cuenta que la incrustación no es realmente un requisito, simplemente hace que sus tipos y su uso sean más fluidos. User podría ser un campo “ordinario” de RequistrationRequest , por ejemplo:

 type RegistrationRequest struct { Usr User // This is just an ordinary field, not embedding Email2 *string } 

Puede usar el paquete ” github.com/jinzhu/copier ” para copiar entre estructuras que contengan el mismo nombre de campo. Este paquete utiliza la reflexión para hacer esto.

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

Salida

  User : John Doe a@b.com johndoe 1234 RegistrationRequest : John Doe a@b.com johndoe 1234