I have a struct and I would like it to be initialised with some sensible default values.
Typically, the thing to do here is to use a constructor but since go isn't really OOP in the traditional sense these aren't true objects and it has no constructors.
I have noticed the init method but that is at the package level. Is there something else similar that can be used at the struct level?
If not what is the accepted best practice for this type of thing in Go?
Go has objects. Objects can have constructors (although not automatic constructors). And finally, Go is an OOP language (data types have methods attached, but admittedly there are endless definitions of what OOP is.)
Nevertheless, the accepted best practice is to write zero or more constructors for your types.
As @dystroy posted his answer before me finishing this answer, let me just add an alternative version of his example constructor, which I would probably write instead as:
The reason I want to show you this version is that pretty often "inline" literals can be used instead of a "constructor" call.
Now
*a == *b
.another way is;
There are some equivalents of constructors for when the zero values can't make sensible default values or for when some parameter is necessary for the struct initialization.
Supposing you have a struct like this :
then, if the zero values aren't fitting, you would typically construct an instance with a
NewThing
function returning a pointer :When your struct is simple enough, you can use this condensed construct :
If you don't want to return a pointer, then a practice is to call the function
makeThing
instead ofNewThing
:Reference : Allocation with new in Effective Go.
There are no default constructors in Go, but you can declare methods for any type. You could make it a habit to declare a method called "Init". Not sure if how this relates to best practices, but it helps keep names short without loosing clarity.
The result is:
If you want to force the factory function usage, name your struct (your class) with the first character in lowercase. Then, it won't be possible to instantiate directly the struct, the factory method will be required.
This visibility based on first character lower/upper case work also for struct field and for the function/method. If you don't want to allow external access, use lower case.
There are actually two accepted best practices:
func New() YourTyp
or if you have several such types in your package functionsfunc NewYourType1() YourType1
and so on.Document if a zero value of your type is usable or not (in which case it has to be set up by one of the
New...
functions. (For the "traditionalist" oops: Someone who does not read the documentation won't be able to use your types properly, even if he cannot create objects in undefined states.)