Use copy or reference for a struct that has a embedded reference type


I was wondering which way below is the correct way of using struct and why?


type UserStorage struct {
    database *sql.DB
    timeout  time.Duration

db1 := UserStorage{ /* pass the args as shown above */ }   // This?
db2 := &UserStorage{ /* pass the args as shown above */ }  // This?

// Then inject `db1` or `db2` to where you need.

There’s nothing more correct or less correct about either. It just changes how you use them.

If a function, updateStorage, expects a *UserStorage pointer, you have to pass db1 as updateStorage(&db1) but you pass db2 as just updateStorage(db2). If you have a readStorage function that expects a UserStorage value, then you have to pass db1 and db2 as readStorage(db1), and readStorage(*db2), respectively.

Function parameters are always pass by value in Go, so this hypothetical readStorage function gets a copy of the UserStorage and cannot mutate the original that was passed in. Functions that receive pointers can mutate the values pointed to by those pointers. You may want to use a UserStorage or *UserStorage based on those details.

If I pass db1 to any function over and over again, a new copy of UserStorage will be created each time in memory and the old one will be removed as soon as functions(s) exit which is something I know. I assume every copy of db1 will always use the existing same reference of database property because it is already a reference to *sql.DB in memory. Is my assumption correct? So there will always be 1 copy of *sql.DB in memory. Same applies if I used db2 too.

Yes, you are correct.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.