I am trying to copy a struct in Go and cannot find many resources on this. Here is what I have:
type Server struct {
HTTPRoot string // Location of the current subdirectory
StaticRoot string // Folder containing static files for all domains
Auth Auth
FormRecipients []string
Router *httprouter.Router
}
func (s *Server) Copy() (c *Server) {
c.HTTPRoot = s.HTTPRoot
c.StaticRoot = s.StaticRoot
c.Auth = s.Auth
c.FormRecipients = s.FormRecipients
c.Router = s.Router
return
}
First question, this will not be a deep copy because I am not copying s.Auth. Is this at least a correct shallow copy? Second question, is there a more idiomatic way to perform a deep (or shallow) copy?
Edit:
One other alternative I've played around with is really simple and uses the fact that arguments are passed by value.
func (s *Server) Copy() (s2 *Server) {
tmp := s
s2 = &tmp
return
}
Is this version any better? (Is it correct?)
Deep copy stores copies of the object's value. Shallow Copy reflects changes made to the new/copied object in the original object. Deep copy doesn't reflect changes made to the new/copied object in the original object. Shallow Copy stores the copy of the original object and points the references to the objects.
In the case of shallow copy, a reference of an object is copied into another object. It means that any changes made to a copy of an object do reflect in the original object.
The default implementation of the clone method creates a shallow copy of the source object, it means a new instance of type Object is created, it copies all the fields to a new instance and returns a new object of type 'Object'. This Object explicitly needs to be typecast in object type of source object.
Creating a copy of an object by copying data of all member variables as it is, is called shallow copy while creating an object by copying data of another object along with the values of memory resources that reside outside the object but handled by that object, is called deep copy.
Assignment is a copy. Your second function comes close, you just need to dereference s
.
This copies the *Server
s
to c
c := new(Server)
*c = *s
As for a deep copy, you need to go through the fields, and determine what needs to be copied recursively. Depending on what *httprouter.Router
is, you may not be able to make a deep copy if it contains data in unexported fields.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With