Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign struct with another struct

Tags:

struct

go

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?

like image 591
tommyd456 Avatar asked Aug 13 '15 07:08

tommyd456


People also ask

Can you assign a struct to another struct?

Yes, you can assign one instance of a struct to another using a simple assignment statement. In the case of non-pointer or non pointer containing struct members, assignment means copy. In the case of pointer struct members, assignment means pointer will point to the same address of the other pointer.

How do you assign a structure variable to another structure variable?

To assign and retrieve values from the elements of a structure variable, you use the same syntax as you use to set and get properties on an object. You place the member access operator ( . ) between the structure variable name and the element name.

Can struct be copied?

A struct variable in Golang can be copied to another variable easily using the assignment statement(=). Any changes made to the second struct will not be reflected back to the first struct.


1 Answers

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 := "[email protected]"
    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 [email protected]

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
}
like image 118
icza Avatar answered Sep 29 '22 13:09

icza